fix a typo.
authorHavoc Pennington <hp@pobox.com>
Fri, 10 Aug 2001 03:46:08 +0000 (03:46 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Fri, 10 Aug 2001 03:46:08 +0000 (03:46 +0000)
2001-08-07  Havoc Pennington  <hp@pobox.com>

* gtk/gtkfilesel.c (open_ref_dir): fix a typo.

* gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
some fixage is needed here, but nothing simple. Owen understands
it. ;-)

        * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
sizing and positioning.  Also, fix bug in compute_geometry_hints
(width/height confusion for setting min size).
(gtk_window_move): new function
(gtk_window_resize): new function
(gtk_window_get_size): new function
(gtk_window_get_position): new function
(gtk_window_parse_geometry): new function

  * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
  (gtk_widget_get_size_request): new function
  (gtk_widget_get_usize): delete, that was a short-lived function
  ;-)
  (gtk_widget_set_usize): deprecate
  (gtk_widget_set_uposition): deprecate, make it a trivial
gtk_window_move() wrapper
(gtk_widget_class_init): remove x/y/width/height properties,
add width_request height_request

        * demos/*: update to avoid deprecated functions

* gtk/gtklayout.c: add x/y child properties

* gtk/gtkfixed.c: add x/y child properties, and get rid of
uses of "gint16"

* tests/testgtk.c (create_window_sizing): lots of tweaks to window
sizing test

* gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
configure events on toplevel windows are always in root window
coordinates, following ICCCM spec that all synthetic events
are in root window coords already, while real events are
in parent window coords. Previously the code assumed that
coords of 0,0 were parent window coords, which was
really broken.

  * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
  warning

  * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS
  and GDK_HINT_USER_SIZE so we can set USSize and USPosition
  hints in gtk_window_parse_geometry()

  * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
  new USER_POS USER_SIZE hints

35 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
demos/gtk-demo/colorsel.c
demos/gtk-demo/item_factory.c
demos/gtk-demo/main.c
demos/gtk-demo/panes.c
demos/gtk-demo/pixbufs.c
demos/pixbuf-demo.c
demos/testpixbuf-drawable.c
demos/testpixbuf-save.c
demos/testpixbuf.c
docs/Changes-2.0.txt
docs/reference/gdk/tmpl/windows.sgml
docs/reference/gtk/tmpl/gtk-unused.sgml
docs/reference/gtk/tmpl/gtkrc.sgml
docs/reference/gtk/tmpl/gtkwidget.sgml
docs/reference/gtk/tmpl/gtkwindow.sgml
docs/sizing-test.txt [new file with mode: 0644]
gdk/gdkwindow.h
gdk/x11/gdkevents-x11.c
gdk/x11/gdkwindow-x11.c
gtk/gtkfixed.c
gtk/gtkfixed.h
gtk/gtklayout.c
gtk/gtkplug.c
gtk/gtkwidget.c
gtk/gtkwidget.h
gtk/gtkwindow.c
gtk/gtkwindow.h
tests/testgtk.c

index 587577f0c2570e246a036015c427213bebb8e1c1..05cb01ade07865033cd871acb1896a8dbc9d80a4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,58 @@
+2001-08-07  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+       * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+       some fixage is needed here, but nothing simple. Owen understands
+       it. ;-)
+
+        * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+       sizing and positioning.  Also, fix bug in compute_geometry_hints
+       (width/height confusion for setting min size). 
+       (gtk_window_move): new function
+       (gtk_window_resize): new function
+       (gtk_window_get_size): new function
+       (gtk_window_get_position): new function
+       (gtk_window_parse_geometry): new function
+       
+       * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+       (gtk_widget_get_size_request): new function
+       (gtk_widget_get_usize): delete, that was a short-lived function
+       ;-)
+       (gtk_widget_set_usize): deprecate
+       (gtk_widget_set_uposition): deprecate, make it a trivial 
+       gtk_window_move() wrapper
+       (gtk_widget_class_init): remove x/y/width/height properties,
+       add width_request height_request
+       
+        * demos/*: update to avoid deprecated functions
+       
+       * gtk/gtklayout.c: add x/y child properties
+
+       * gtk/gtkfixed.c: add x/y child properties, and get rid of 
+       uses of "gint16"
+
+       * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+       sizing test
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+       configure events on toplevel windows are always in root window
+       coordinates, following ICCCM spec that all synthetic events 
+       are in root window coords already, while real events are 
+       in parent window coords. Previously the code assumed that 
+       coords of 0,0 were parent window coords, which was 
+       really broken.
+  
+       * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+       warning
+       * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS 
+       and GDK_HINT_USER_SIZE so we can set USSize and USPosition 
+       hints in gtk_window_parse_geometry()
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+       new USER_POS USER_SIZE hints    
+
 2001-08-09  Matthias Clasen  <matthiasc@waldgeist.poet.de>
 
        * tests/prop-editor.c (properties_from_type): Use 
index 587577f0c2570e246a036015c427213bebb8e1c1..05cb01ade07865033cd871acb1896a8dbc9d80a4 100644 (file)
@@ -1,3 +1,58 @@
+2001-08-07  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+       * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+       some fixage is needed here, but nothing simple. Owen understands
+       it. ;-)
+
+        * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+       sizing and positioning.  Also, fix bug in compute_geometry_hints
+       (width/height confusion for setting min size). 
+       (gtk_window_move): new function
+       (gtk_window_resize): new function
+       (gtk_window_get_size): new function
+       (gtk_window_get_position): new function
+       (gtk_window_parse_geometry): new function
+       
+       * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+       (gtk_widget_get_size_request): new function
+       (gtk_widget_get_usize): delete, that was a short-lived function
+       ;-)
+       (gtk_widget_set_usize): deprecate
+       (gtk_widget_set_uposition): deprecate, make it a trivial 
+       gtk_window_move() wrapper
+       (gtk_widget_class_init): remove x/y/width/height properties,
+       add width_request height_request
+       
+        * demos/*: update to avoid deprecated functions
+       
+       * gtk/gtklayout.c: add x/y child properties
+
+       * gtk/gtkfixed.c: add x/y child properties, and get rid of 
+       uses of "gint16"
+
+       * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+       sizing test
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+       configure events on toplevel windows are always in root window
+       coordinates, following ICCCM spec that all synthetic events 
+       are in root window coords already, while real events are 
+       in parent window coords. Previously the code assumed that 
+       coords of 0,0 were parent window coords, which was 
+       really broken.
+  
+       * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+       warning
+       * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS 
+       and GDK_HINT_USER_SIZE so we can set USSize and USPosition 
+       hints in gtk_window_parse_geometry()
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+       new USER_POS USER_SIZE hints    
+
 2001-08-09  Matthias Clasen  <matthiasc@waldgeist.poet.de>
 
        * tests/prop-editor.c (properties_from_type): Use 
index 587577f0c2570e246a036015c427213bebb8e1c1..05cb01ade07865033cd871acb1896a8dbc9d80a4 100644 (file)
@@ -1,3 +1,58 @@
+2001-08-07  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+       * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+       some fixage is needed here, but nothing simple. Owen understands
+       it. ;-)
+
+        * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+       sizing and positioning.  Also, fix bug in compute_geometry_hints
+       (width/height confusion for setting min size). 
+       (gtk_window_move): new function
+       (gtk_window_resize): new function
+       (gtk_window_get_size): new function
+       (gtk_window_get_position): new function
+       (gtk_window_parse_geometry): new function
+       
+       * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+       (gtk_widget_get_size_request): new function
+       (gtk_widget_get_usize): delete, that was a short-lived function
+       ;-)
+       (gtk_widget_set_usize): deprecate
+       (gtk_widget_set_uposition): deprecate, make it a trivial 
+       gtk_window_move() wrapper
+       (gtk_widget_class_init): remove x/y/width/height properties,
+       add width_request height_request
+       
+        * demos/*: update to avoid deprecated functions
+       
+       * gtk/gtklayout.c: add x/y child properties
+
+       * gtk/gtkfixed.c: add x/y child properties, and get rid of 
+       uses of "gint16"
+
+       * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+       sizing test
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+       configure events on toplevel windows are always in root window
+       coordinates, following ICCCM spec that all synthetic events 
+       are in root window coords already, while real events are 
+       in parent window coords. Previously the code assumed that 
+       coords of 0,0 were parent window coords, which was 
+       really broken.
+  
+       * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+       warning
+       * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS 
+       and GDK_HINT_USER_SIZE so we can set USSize and USPosition 
+       hints in gtk_window_parse_geometry()
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+       new USER_POS USER_SIZE hints    
+
 2001-08-09  Matthias Clasen  <matthiasc@waldgeist.poet.de>
 
        * tests/prop-editor.c (properties_from_type): Use 
index 587577f0c2570e246a036015c427213bebb8e1c1..05cb01ade07865033cd871acb1896a8dbc9d80a4 100644 (file)
@@ -1,3 +1,58 @@
+2001-08-07  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+       * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+       some fixage is needed here, but nothing simple. Owen understands
+       it. ;-)
+
+        * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+       sizing and positioning.  Also, fix bug in compute_geometry_hints
+       (width/height confusion for setting min size). 
+       (gtk_window_move): new function
+       (gtk_window_resize): new function
+       (gtk_window_get_size): new function
+       (gtk_window_get_position): new function
+       (gtk_window_parse_geometry): new function
+       
+       * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+       (gtk_widget_get_size_request): new function
+       (gtk_widget_get_usize): delete, that was a short-lived function
+       ;-)
+       (gtk_widget_set_usize): deprecate
+       (gtk_widget_set_uposition): deprecate, make it a trivial 
+       gtk_window_move() wrapper
+       (gtk_widget_class_init): remove x/y/width/height properties,
+       add width_request height_request
+       
+        * demos/*: update to avoid deprecated functions
+       
+       * gtk/gtklayout.c: add x/y child properties
+
+       * gtk/gtkfixed.c: add x/y child properties, and get rid of 
+       uses of "gint16"
+
+       * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+       sizing test
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+       configure events on toplevel windows are always in root window
+       coordinates, following ICCCM spec that all synthetic events 
+       are in root window coords already, while real events are 
+       in parent window coords. Previously the code assumed that 
+       coords of 0,0 were parent window coords, which was 
+       really broken.
+  
+       * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+       warning
+       * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS 
+       and GDK_HINT_USER_SIZE so we can set USSize and USPosition 
+       hints in gtk_window_parse_geometry()
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+       new USER_POS USER_SIZE hints    
+
 2001-08-09  Matthias Clasen  <matthiasc@waldgeist.poet.de>
 
        * tests/prop-editor.c (properties_from_type): Use 
index 587577f0c2570e246a036015c427213bebb8e1c1..05cb01ade07865033cd871acb1896a8dbc9d80a4 100644 (file)
@@ -1,3 +1,58 @@
+2001-08-07  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+       * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+       some fixage is needed here, but nothing simple. Owen understands
+       it. ;-)
+
+        * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+       sizing and positioning.  Also, fix bug in compute_geometry_hints
+       (width/height confusion for setting min size). 
+       (gtk_window_move): new function
+       (gtk_window_resize): new function
+       (gtk_window_get_size): new function
+       (gtk_window_get_position): new function
+       (gtk_window_parse_geometry): new function
+       
+       * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+       (gtk_widget_get_size_request): new function
+       (gtk_widget_get_usize): delete, that was a short-lived function
+       ;-)
+       (gtk_widget_set_usize): deprecate
+       (gtk_widget_set_uposition): deprecate, make it a trivial 
+       gtk_window_move() wrapper
+       (gtk_widget_class_init): remove x/y/width/height properties,
+       add width_request height_request
+       
+        * demos/*: update to avoid deprecated functions
+       
+       * gtk/gtklayout.c: add x/y child properties
+
+       * gtk/gtkfixed.c: add x/y child properties, and get rid of 
+       uses of "gint16"
+
+       * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+       sizing test
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+       configure events on toplevel windows are always in root window
+       coordinates, following ICCCM spec that all synthetic events 
+       are in root window coords already, while real events are 
+       in parent window coords. Previously the code assumed that 
+       coords of 0,0 were parent window coords, which was 
+       really broken.
+  
+       * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+       warning
+       * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS 
+       and GDK_HINT_USER_SIZE so we can set USSize and USPosition 
+       hints in gtk_window_parse_geometry()
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+       new USER_POS USER_SIZE hints    
+
 2001-08-09  Matthias Clasen  <matthiasc@waldgeist.poet.de>
 
        * tests/prop-editor.c (properties_from_type): Use 
index 587577f0c2570e246a036015c427213bebb8e1c1..05cb01ade07865033cd871acb1896a8dbc9d80a4 100644 (file)
@@ -1,3 +1,58 @@
+2001-08-07  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+       * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+       some fixage is needed here, but nothing simple. Owen understands
+       it. ;-)
+
+        * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+       sizing and positioning.  Also, fix bug in compute_geometry_hints
+       (width/height confusion for setting min size). 
+       (gtk_window_move): new function
+       (gtk_window_resize): new function
+       (gtk_window_get_size): new function
+       (gtk_window_get_position): new function
+       (gtk_window_parse_geometry): new function
+       
+       * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+       (gtk_widget_get_size_request): new function
+       (gtk_widget_get_usize): delete, that was a short-lived function
+       ;-)
+       (gtk_widget_set_usize): deprecate
+       (gtk_widget_set_uposition): deprecate, make it a trivial 
+       gtk_window_move() wrapper
+       (gtk_widget_class_init): remove x/y/width/height properties,
+       add width_request height_request
+       
+        * demos/*: update to avoid deprecated functions
+       
+       * gtk/gtklayout.c: add x/y child properties
+
+       * gtk/gtkfixed.c: add x/y child properties, and get rid of 
+       uses of "gint16"
+
+       * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+       sizing test
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+       configure events on toplevel windows are always in root window
+       coordinates, following ICCCM spec that all synthetic events 
+       are in root window coords already, while real events are 
+       in parent window coords. Previously the code assumed that 
+       coords of 0,0 were parent window coords, which was 
+       really broken.
+  
+       * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+       warning
+       * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS 
+       and GDK_HINT_USER_SIZE so we can set USSize and USPosition 
+       hints in gtk_window_parse_geometry()
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+       new USER_POS USER_SIZE hints    
+
 2001-08-09  Matthias Clasen  <matthiasc@waldgeist.poet.de>
 
        * tests/prop-editor.c (properties_from_type): Use 
index 587577f0c2570e246a036015c427213bebb8e1c1..05cb01ade07865033cd871acb1896a8dbc9d80a4 100644 (file)
@@ -1,3 +1,58 @@
+2001-08-07  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+       * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+       some fixage is needed here, but nothing simple. Owen understands
+       it. ;-)
+
+        * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+       sizing and positioning.  Also, fix bug in compute_geometry_hints
+       (width/height confusion for setting min size). 
+       (gtk_window_move): new function
+       (gtk_window_resize): new function
+       (gtk_window_get_size): new function
+       (gtk_window_get_position): new function
+       (gtk_window_parse_geometry): new function
+       
+       * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+       (gtk_widget_get_size_request): new function
+       (gtk_widget_get_usize): delete, that was a short-lived function
+       ;-)
+       (gtk_widget_set_usize): deprecate
+       (gtk_widget_set_uposition): deprecate, make it a trivial 
+       gtk_window_move() wrapper
+       (gtk_widget_class_init): remove x/y/width/height properties,
+       add width_request height_request
+       
+        * demos/*: update to avoid deprecated functions
+       
+       * gtk/gtklayout.c: add x/y child properties
+
+       * gtk/gtkfixed.c: add x/y child properties, and get rid of 
+       uses of "gint16"
+
+       * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+       sizing test
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+       configure events on toplevel windows are always in root window
+       coordinates, following ICCCM spec that all synthetic events 
+       are in root window coords already, while real events are 
+       in parent window coords. Previously the code assumed that 
+       coords of 0,0 were parent window coords, which was 
+       really broken.
+  
+       * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+       warning
+       * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS 
+       and GDK_HINT_USER_SIZE so we can set USSize and USPosition 
+       hints in gtk_window_parse_geometry()
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+       new USER_POS USER_SIZE hints    
+
 2001-08-09  Matthias Clasen  <matthiasc@waldgeist.poet.de>
 
        * tests/prop-editor.c (properties_from_type): Use 
index cd178288b72438bd806d3509b6c2fa6acec5197b..da02ef39c443affc82e87e94c0dc76d2840265a3 100644 (file)
@@ -78,7 +78,7 @@ do_colorsel (void)
       
       da = gtk_drawing_area_new ();
       /* set a minimum size */
-      gtk_widget_set_usize (da, 200, 200);
+      gtk_widget_set_size_request (da, 200, 200);
       /* set the color */
       gtk_widget_modify_bg (da, GTK_STATE_NORMAL, &color);
       
index 5454a074d82b08e3a194e8b29ba4301001c50d41..5a55de4b679928807d54b6f96dd55b174c562e7d 100644 (file)
@@ -92,7 +92,7 @@ do_item_factory (void)
                          FALSE, FALSE, 0);
 
       label = gtk_label_new ("Type\n<alt>\nto start");
-      gtk_widget_set_usize (label, 200, 200);
+      gtk_widget_set_size_request (label, 200, 200);
       gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
 
index d06070ed0c70ef5c70cdf58ba121ee80f08052fa..77fb6bc0ceb99203a62684b5a81afad80348ff10 100644 (file)
@@ -686,7 +686,7 @@ create_tree (void)
 
   gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection),
                               GTK_TREE_SELECTION_SINGLE);
-  gtk_widget_set_usize (tree_view, 200, -1);
+  gtk_widget_set_size_request (tree_view, 200, -1);
 
   for (i=0; i < G_N_ELEMENTS (testgtk_demos); i++)
     {
index f86d74ac5c0d2a2d1c7e5843d99e19406f8b3be1..3e1032976203bc5d28aafc4aed519525f4ee3e83 100644 (file)
@@ -148,7 +148,7 @@ do_panes (void)
 
       frame = gtk_frame_new (NULL);
       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
-      gtk_widget_set_usize (frame, 60, 60);
+      gtk_widget_set_size_request (frame, 60, 60);
       gtk_paned_add1 (GTK_PANED (hpaned), frame);
       
       button = gtk_button_new_with_mnemonic ("_Hi there");
index d40c0918c3665dc8ffeb789d7b35341683598e9a..d0f2f2a4efbb359e226ab395f1e8fd645ef34bf5 100644 (file)
@@ -246,7 +246,7 @@ do_pixbufs (void)
        }
       else
        {
-         gtk_widget_set_usize (window, back_width, back_height);
+         gtk_widget_set_size_request (window, back_width, back_height);
 
          frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height);
 
index 11b5e1a15f9bf98cf2b2f1840c95c11ba29186c9..722007ac71ede54f008f273a5efb8d1c7a54b607 100644 (file)
@@ -212,8 +212,9 @@ main (int argc, char **argv)
        frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height);
 
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-       gtk_widget_set_usize (window, back_width, back_height);
-       gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
+
+       gtk_widget_set_size_request (window, back_width, back_height);
+        gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
 
        gtk_signal_connect (GTK_OBJECT (window), "destroy",
                            GTK_SIGNAL_FUNC (destroy_cb), NULL);
index 073b8fa4982fbf5786f5e30e4750f178bd957d59..be40573cbebc089a052fbc3001deeb0aa0fa1041 100644 (file)
@@ -104,9 +104,9 @@ int main(int argc, char **argv)
    gtk_container_add(GTK_CONTAINER(window), vbox);  
    
    drawing_area = gtk_drawing_area_new();
-   gtk_widget_set_usize(GTK_WIDGET(drawing_area),
-                        gdk_pixbuf_get_width (pixbuf),
-                        gdk_pixbuf_get_height (pixbuf));
+   gtk_widget_set_size_request (GTK_WIDGET(drawing_area),
+                                gdk_pixbuf_get_width (pixbuf),
+                                gdk_pixbuf_get_height (pixbuf));
    gtk_signal_connect(GTK_OBJECT(drawing_area), "expose_event",
                       GTK_SIGNAL_FUNC(expose_cb), NULL);
 
index ed07bd4dd7586662010dd8ab1c1582e770385174..071352ace54c30ea747b696f1e706cc802770888 100644 (file)
@@ -142,9 +142,9 @@ main (int argc, char **argv)
         gtk_container_add (GTK_CONTAINER (window), vbox);  
    
         drawing_area = gtk_drawing_area_new ();
-        gtk_widget_set_usize (GTK_WIDGET (drawing_area),
-                              gdk_pixbuf_get_width (pixbuf),
-                              gdk_pixbuf_get_height (pixbuf));
+        gtk_widget_set_size_request (GTK_WIDGET (drawing_area),
+                                     gdk_pixbuf_get_width (pixbuf),
+                                     gdk_pixbuf_get_height (pixbuf));
         gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
                             GTK_SIGNAL_FUNC (expose_cb), NULL);
 
index 8f80d31180554e1b167163bf6911dd4a93f810b1..707398f8df64ab273493a38698dd2b2781032c1b 100644 (file)
@@ -393,7 +393,7 @@ new_testrgb_window (GdkPixbuf *pixbuf, gchar *title)
        drawing_area = gtk_drawing_area_new ();
 
        temp_box = gtk_hbox_new (FALSE, 0);
-       gtk_widget_set_usize (GTK_WIDGET(drawing_area), w, h);
+       gtk_widget_set_size_request (GTK_WIDGET(drawing_area), w, h);
        gtk_box_pack_start (GTK_BOX (temp_box), drawing_area, FALSE, FALSE, 0);
        gtk_box_pack_start (GTK_BOX (vbox), temp_box, FALSE, FALSE, 0);
        
index ffce736df0a8cff9fda66be1ed5b132106d277d9..9b82b2d85a1cc18eef577505a7fe7e642046edea 100644 (file)
@@ -397,6 +397,22 @@ Incompatible Changes from GTK+-1.2 to GTK+-2.0:
   using gdk_image_get() should really be ported to
   gdk_pixbuf_get_from_drawable().
 
+* gtk_widget_set_usize() has been renamed to
+  gtk_widget_set_size_request(), however the old name still exists
+  unless you define GTK_DISABLE_DEPRECATED.
+
+* gtk_widget_set_uposition() is deprecated; use gtk_window_move(), 
+  gtk_fixed_put(), or gtk_layout_put() instead.
+
+* gtk_window_set_policy() is deprecated. To get the effect of
+  "allow_shrink", call gtk_widget_set_size_request(window, 0, 0).  To
+  get the effect of "allow_grow", call
+  gtk_window_set_resizable(window, TRUE). You didn't want the effect
+  of auto_shrink, it made no sense. But maybe if you were using it you
+  want to use gtk_window_resize (window, 1, 1) to snap a window back
+  to its minimum size (the 1, 1 will be rounded up to the minimum
+  window size).
+
 * The core GTK+ now takes care of handling mapping, unmapping and
   realizing the child widgets of containers in
   gtk_widget_set_parent(). In most cases, this allows container
index 78e0bc8f112a1f118eabe25edfc0f8d6f37b1114..c21b8f46f29003d04c5496b51bac619f2e95292e 100644 (file)
@@ -87,6 +87,8 @@ Windows
 @GDK_HINT_ASPECT: 
 @GDK_HINT_RESIZE_INC: 
 @GDK_HINT_WIN_GRAVITY: 
+@GDK_HINT_USER_POS: 
+@GDK_HINT_USER_SIZE: 
 
 <!-- ##### STRUCT GdkGeometry ##### -->
 <para>
index 8c126874d3ee7672a7b166ac164651f0144aede5..3c9c63eebe90700ad0cfb0f3d4ce5735764e259f 100644 (file)
@@ -1004,6 +1004,36 @@ the #GtkAdjustment which sets the range of the scale.
 
 @widget: the object which received the signal.
 
+<!-- ##### ARG GtkWidget:height ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GtkWidget:width ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GtkWidget:x ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GtkWidget:y ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GtkWindow:auto-shrink ##### -->
+<para>
+If the window shrinks automatically when widgets within it shrink.
+</para>
+
+
 <!-- ##### FUNCTION gtk_arg_copy ##### -->
 <para>
 It will either copy data into an existing argument or allocate a new argument
index cc0b23b6d217a6b8beefca09d47e350a7eb6068a..30ffca8235aa804f9d0033f0f1ed9b6a61d8fd94 100644 (file)
@@ -495,7 +495,6 @@ This can later be composited together with other
 #GtkRcStyle structures to form a #GtkStyle.
 </para>
 
-@parent_instance: 
 @name: 
 @bg_pixmap_name: 
 @font_desc: 
index 01e7f0763bfe3501444fa2ba345e1c4917c783fe..b92fb889ee5f4a394cf4f04bbd94a27b6525058a 100644 (file)
@@ -1874,22 +1874,12 @@ a widget changes from un-anchored to anchored or vice-versa.
 
 </para>
 
-<!-- ##### ARG GtkWidget:x ##### -->
+<!-- ##### ARG GtkWidget:width-request ##### -->
 <para>
 
 </para>
 
-<!-- ##### ARG GtkWidget:y ##### -->
-<para>
-
-</para>
-
-<!-- ##### ARG GtkWidget:width ##### -->
-<para>
-
-</para>
-
-<!-- ##### ARG GtkWidget:height ##### -->
+<!-- ##### ARG GtkWidget:height-request ##### -->
 <para>
 
 </para>
index 7d43fb870ac681f78775fe19888fd650ff709a26..3fb16a1c65f9a5d105ed7e595d4e24cb0555b846 100644 (file)
@@ -509,11 +509,6 @@ The type of the window.
 The title of the window.
 </para>
 
-<!-- ##### ARG GtkWindow:auto-shrink ##### -->
-<para>
-If the window shrinks automatically when widgets within it shrink.
-</para>
-
 <!-- ##### ARG GtkWindow:allow-shrink ##### -->
 <para>
 If the window can be resized to a smaller size by the user.
diff --git a/docs/sizing-test.txt b/docs/sizing-test.txt
new file mode 100644 (file)
index 0000000..6954612
--- /dev/null
@@ -0,0 +1,121 @@
+This is a list of things to check when testing window size/pos functions.
+===
+
+gtk_widget_set_size_request():
+ - causes the widget to request the given size
+ - for toplevel windows, changes the default-requested size if 
+   no default size is set and gtk_window_resize() has not been called
+ - passing -1 for either width or height reverts to "natural" request
+   in that dimension
+ - passing 0 is allowed, and results in requisition of 1x1 
+   (0x0 is a permitted requisition, but equivalent to 1x1, 
+   we use 1x1 for implementation convenience)
+ - causes notifies on width_request, height_request properties
+
+gtk_window_resize():
+ - causes a configure request in all cases if the window is mapped, 
+   unless the new size is the same as the old size
+ - overrides the default size on map if the window is unmapped
+ - allows size of 0, equivalent to 1
+ - clamped to geometry hints
+
+gtk_window_set_default_size():
+ - has no effect after the window has been mapped the first time, 
+   unless the window has been unrealized in which case it should 
+   have an effect
+ - allows size of 0, equivalent to 1
+ - allows size of -1 to unset the default size
+ - clamped to geometry hints
+ - gtk_window_resize() overrides it
+ - causes notifies on default_width, default_height properties
+
+gtk_window_get_default_size():
+ - returns the values last passed to set_default_size(), including 
+   -1. If set_default_size() has not been called, returns -1.
+
+gtk_window_move():
+ - always causes a configure request if the window is mapped, 
+   unless the last configure request we sent was for the same
+   position being moved to
+ - position may be negative to move windows offscreen
+ - if GTK_WIN_POS_CENTER_ALWAYS (or other future position 
+   constraints we may add) is in effect, the move
+   request is clamped to obey the constraints. thus
+   calling gtk_window_move() on a CENTER_ALWAYS window 
+   may trigger the window to bounce back to center if it 
+   wasn't there
+ - overrides all GTK_WIN_POS_ except CENTER_ALWAYS
+
+gtk_window_get_size():
+ - obtains the client-side known size of widget->window, 
+   as last received from a configure event
+ - prior to mapping, returns the default size we will request
+ - between realization and mapping, computes default size 
+   rather than looking at widget->window up-to-date size, 
+   so the size will be correct after force-realizing a window
+
+gtk_window_get_position():
+ - obtains the point to be passed to gtk_window_move() in order
+   to keep the window in its current position
+ - round-trips to the server to get the position; this is suboptimal
+   from both a race condition and speed standpoint but required to get
+   window frame size
+ - if the window is unmapped, returns the default position we will 
+   request
+
+gtk_window_set_position():
+ - not the inverse of get_position(), sadly
+ - modifies the default positioning of the window
+ - if set to CENTER_ALWAYS and the window is mapped, results in a
+   configure request moving the window to the center, unless the 
+   window was already centered
+ - ignored if gtk_window_move() called, with the exception 
+   of CENTER_ALWAYS
+
+gtk_window_parse_geometry():
+ - parses a standard X geometry string
+ - toggles on one or both of GDK_HINT_USER_SIZE, GDK_HINT_USER_POS
+ - "xprop" shows user size/position are set on the window
+ - calls gtk_window_set_default_size() to set the window size
+ - calls gtk_window_move() to set the window position
+ - calls gtk_window_set_gravity() to set the window gravity
+
+gtk_window_reshow_with_initial_size():
+ - for use by GUI builders; unrealizes and re-shows the window, 
+   using default size (and also position, but position 
+   is reset on any hide anyway)
+ - window should be positioned and sized as it was on initial map,
+   barring odd window managers
+
+gtk_window_set_geometry_hints():
+ - if a hint is set with this function, we do not override it
+   in other parts of the code
+
+General behavior
+===
+
+ - no infinite loops or nasty fighting-the-user flicker during 
+   operations such as moving/resizing a window
+
+Properties
+===
+
+GtkWindow::default_width, GtkWindow::default_height:
+ - default_width is -1 if unset, or >= 0 if 
+   a default width is set
+ - default_height is -1 if unset, or >= 0 if
+   a default height is set
+
+GtkWindow::allow_grow, GtkWindow::resizable:
+ - equivalent properties; changing one notifies on the other
+ - if FALSE, we set the min size to the max size in the geometry 
+   hints. 
+ - If the app programmer has called gtk_window_set_geometry_hints()
+   however and set min or max size, we don't replace the hint they
+   set.
+
+GtkWidget::width_request, GtkWidget::height_request:
+ - if -1, default requisition of widget is used
+ - otherwise, override default requisition
+
+
index 03263adef8e41255ef8bb43142f085e14c9d0e75..425cfe871dff5c22ee57fa9433a2525298ffcdb1 100644 (file)
@@ -82,7 +82,9 @@ typedef enum
   GDK_HINT_BASE_SIZE   = 1 << 3,
   GDK_HINT_ASPECT      = 1 << 4,
   GDK_HINT_RESIZE_INC  = 1 << 5,
-  GDK_HINT_WIN_GRAVITY = 1 << 6
+  GDK_HINT_WIN_GRAVITY = 1 << 6,
+  GDK_HINT_USER_POS    = 1 << 7,
+  GDK_HINT_USER_SIZE   = 1 << 8
 } GdkWindowHints;
 
 
index 593c8d720c7e4cf8f181cfb574430f7201cc7a2f..a757e6bbfce0b4f332bc03f020fb8997f871689f 100644 (file)
@@ -1309,7 +1309,9 @@ gdk_event_translate (GdkEvent *event,
          (window_private->extension_events != 0))
        _gdk_input_configure_event (&xevent->xconfigure, window);
 
-      if (!window || GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
+      if (!window ||
+          GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD ||
+          GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
        return_val = FALSE;
       else
        {
@@ -1318,8 +1320,7 @@ gdk_event_translate (GdkEvent *event,
          event->configure.width = xevent->xconfigure.width;
          event->configure.height = xevent->xconfigure.height;
          
-         if (!xevent->xconfigure.x &&
-             !xevent->xconfigure.y &&
+         if (!xevent->xconfigure.send_event && 
              !GDK_WINDOW_DESTROYED (window))
            {
              gint tx = 0;
index c94f7a463d272c233e8c2ac63047574b94ccdcb3..169cdb3a1b69bee59b9bf7dded8a2b71794bd6a7 100644 (file)
@@ -1387,6 +1387,16 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
       size_hints.x = 0;
       size_hints.y = 0;
     }
+
+  if (geom_mask & GDK_HINT_USER_POS)
+    {
+      size_hints.flags |= USPosition;
+    }
+
+  if (geom_mask & GDK_HINT_USER_SIZE)
+    {
+      size_hints.flags |= USSize;
+    }
   
   if (geom_mask & GDK_HINT_MIN_SIZE)
     {
index 3b214886a8fb40be6cb17e0cdd56ed68b8c6b3e8..7e3cdff7d20752d90a6a61a36a6ffa4e1856a0b6 100644 (file)
  */
 
 #include "gtkfixed.h"
+#include "gtkintl.h"
 
+enum {
+  CHILD_PROP_0,
+  CHILD_PROP_X,
+  CHILD_PROP_Y
+};
 
 static void gtk_fixed_class_init    (GtkFixedClass    *klass);
 static void gtk_fixed_init          (GtkFixed         *fixed);
@@ -44,6 +50,16 @@ static void gtk_fixed_forall        (GtkContainer     *container,
                                     gpointer          callback_data);
 static GtkType gtk_fixed_child_type (GtkContainer     *container);
 
+static void gtk_fixed_set_child_property (GtkContainer *container,
+                                          GtkWidget    *child,
+                                          guint         property_id,
+                                          const GValue *value,
+                                          GParamSpec   *pspec);
+static void gtk_fixed_get_child_property (GtkContainer *container,
+                                          GtkWidget    *child,
+                                          guint         property_id,
+                                          GValue       *value,
+                                          GParamSpec   *pspec);
 
 static GtkContainerClass *parent_class = NULL;
 
@@ -94,6 +110,29 @@ gtk_fixed_class_init (GtkFixedClass *class)
   container_class->remove = gtk_fixed_remove;
   container_class->forall = gtk_fixed_forall;
   container_class->child_type = gtk_fixed_child_type;
+
+  container_class->set_child_property = gtk_fixed_set_child_property;
+  container_class->get_child_property = gtk_fixed_get_child_property;
+
+  gtk_container_class_install_child_property (container_class,
+                                             CHILD_PROP_X,
+                                             g_param_spec_int ("x",
+                                                                _("X position"),
+                                                                _("X position of child widget"),
+                                                                G_MININT,
+                                                                G_MAXINT,
+                                                                0,
+                                                                G_PARAM_READWRITE));
+
+  gtk_container_class_install_child_property (container_class,
+                                             CHILD_PROP_Y,
+                                             g_param_spec_int ("y",
+                                                                _("Y position"),
+                                                                _("Y position of child widget"),
+                                                                G_MININT,
+                                                                G_MAXINT,
+                                                                0,
+                                                                G_PARAM_READWRITE));
 }
 
 static GtkType
@@ -119,11 +158,32 @@ gtk_fixed_new (void)
   return GTK_WIDGET (fixed);
 }
 
+static GtkFixedChild*
+get_child (GtkFixed  *fixed,
+           GtkWidget *widget)
+{
+  GList *children;
+  
+  children = fixed->children;
+  while (children)
+    {
+      GtkFixedChild *child;
+      
+      child = children->data;
+      children = children->next;
+
+      if (child->widget == widget)
+        return child;
+    }
+
+  return NULL;
+}
+
 void
 gtk_fixed_put (GtkFixed       *fixed,
                GtkWidget      *widget,
-               gint16         x,
-               gint16         y)
+               gint            x,
+               gint            y)
 {
   GtkFixedChild *child_info;
 
@@ -137,20 +197,121 @@ gtk_fixed_put (GtkFixed       *fixed,
 
   gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
 
-  fixed->children = g_list_append (fixed->children, child_info); 
+  fixed->children = g_list_append (fixed->children, child_info);
+}
+
+static void
+gtk_fixed_move_internal (GtkFixed       *fixed,
+                         GtkWidget      *widget,
+                         gboolean        change_x,
+                         gint            x,
+                         gboolean        change_y,
+                         gint            y)
+{
+  GtkFixedChild *child;
+  
+  g_return_if_fail (GTK_IS_FIXED (fixed));
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (widget->parent == GTK_WIDGET (fixed));  
+  
+  child = get_child (fixed, widget);
+
+  g_assert (child);
+
+  gtk_widget_freeze_child_notify (widget);
+  
+  if (change_x)
+    {
+      child->x = x;
+      gtk_widget_child_notify (widget, "x");
+    }
+
+  if (change_y)
+    {
+      child->y = y;
+      gtk_widget_child_notify (widget, "y");
+    }
+
+  gtk_widget_thaw_child_notify (widget);
+  
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
+    gtk_widget_queue_resize (GTK_WIDGET (fixed));
 }
 
 void
 gtk_fixed_move (GtkFixed       *fixed,
                 GtkWidget      *widget,
-                gint16         x,
-                gint16         y)
+                gint            x,
+                gint            y)
+{
+  g_return_if_fail (GTK_IS_FIXED (fixed));
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (widget->parent == GTK_WIDGET (fixed));
+
+  gtk_fixed_move_internal (fixed, widget, TRUE, x, TRUE, y);
+}
+
+static void
+gtk_fixed_set_child_property (GtkContainer    *container,
+                              GtkWidget       *child,
+                              guint            property_id,
+                              const GValue    *value,
+                              GParamSpec      *pspec)
+{
+  switch (property_id)
+    {
+    case CHILD_PROP_X:
+      gtk_fixed_move_internal (GTK_FIXED (container),
+                               child,
+                               TRUE, g_value_get_int (value),
+                               FALSE, 0);
+      break;
+    case CHILD_PROP_Y:
+      gtk_fixed_move_internal (GTK_FIXED (container),
+                               child,
+                               FALSE, 0,
+                               TRUE, g_value_get_int (value));
+      break;
+    default:
+      GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_fixed_get_child_property (GtkContainer *container,
+                              GtkWidget    *child,
+                              guint         property_id,
+                              GValue       *value,
+                              GParamSpec   *pspec)
 {
+  GtkFixedChild *fixed_child;
+
+  fixed_child = get_child (GTK_FIXED (container), child);
+  
+  switch (property_id)
+    {
+    case CHILD_PROP_X:
+      g_value_set_int (value, fixed_child->x);
+      break;
+    case CHILD_PROP_Y:
+      g_value_set_int (value, fixed_child->y);
+      break;
+    default:
+      GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_fixed_map (GtkWidget *widget)
+{
+  GtkFixed *fixed;
   GtkFixedChild *child;
   GList *children;
 
-  g_return_if_fail (GTK_IS_FIXED (fixed));
-  g_return_if_fail (widget != NULL);
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  fixed = GTK_FIXED (widget);
 
   children = fixed->children;
   while (children)
@@ -158,17 +319,12 @@ gtk_fixed_move (GtkFixed       *fixed,
       child = children->data;
       children = children->next;
 
-      if (child->widget == widget)
-        {
-          child->x = x;
-          child->y = y;
-
-          if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
-            gtk_widget_queue_resize (GTK_WIDGET (fixed));
-
-          break;
-        }
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+         !GTK_WIDGET_MAPPED (child->widget))
+       gtk_widget_map (child->widget);
     }
+
+  gdk_window_show (widget->window);
 }
 
 static void
index 95b49d68e5b344b970dd3ff788f57a75c5afed95..6e0bc593a48f89a97b464a7199f66528242a61eb 100644 (file)
@@ -64,8 +64,8 @@ struct _GtkFixedClass
 struct _GtkFixedChild
 {
   GtkWidget *widget;
-  gint16 x;
-  gint16 y;
+  gint x;
+  gint y;
 };
 
 
@@ -73,12 +73,12 @@ GtkType    gtk_fixed_get_type          (void) G_GNUC_CONST;
 GtkWidget* gtk_fixed_new               (void);
 void       gtk_fixed_put               (GtkFixed       *fixed,
                                         GtkWidget      *widget,
-                                        gint16         x,
-                                        gint16         y);
+                                        gint            x,
+                                        gint            y);
 void       gtk_fixed_move              (GtkFixed       *fixed,
                                         GtkWidget      *widget,
-                                        gint16         x,
-                                        gint16         y);
+                                        gint            x,
+                                        gint            y);
 
 #ifdef __cplusplus
 }
index c50290509a91dd44a386a5b7bedc0195946cfda5..07c0a89b564527291bfaf91f72ac18229f136238 100644 (file)
@@ -51,44 +51,56 @@ enum {
    PROP_HEIGHT
 };
 
-static void     gtk_layout_class_init         (GtkLayoutClass *class);
-static void     gtk_layout_get_property       (GObject        *object,
-                                              guint          prop_id,
-                                              GValue         *value,
-                                              GParamSpec     *pspec);
-static void     gtk_layout_set_property       (GObject        *object,
-                                              guint          prop_id,
-                                              const GValue   *value,
-                                              GParamSpec     *pspec);
-static void     gtk_layout_init               (GtkLayout      *layout);
-
-static void     gtk_layout_finalize           (GObject        *object);
-static void     gtk_layout_realize            (GtkWidget      *widget);
-static void     gtk_layout_unrealize          (GtkWidget      *widget);
-static void     gtk_layout_map                (GtkWidget      *widget);
-static void     gtk_layout_size_request       (GtkWidget      *widget,
-                                              GtkRequisition *requisition);
-static void     gtk_layout_size_allocate      (GtkWidget      *widget,
-                                              GtkAllocation  *allocation);
-static gint     gtk_layout_expose             (GtkWidget      *widget, 
-                                              GdkEventExpose *event);
-
-static void     gtk_layout_remove             (GtkContainer *container, 
-                                              GtkWidget    *widget);
-static void     gtk_layout_forall             (GtkContainer *container,
-                                              gboolean      include_internals,
-                                              GtkCallback   callback,
-                                              gpointer      callback_data);
-static void     gtk_layout_set_adjustments    (GtkLayout     *layout,
-                                              GtkAdjustment *hadj,
-                                              GtkAdjustment *vadj);
-
-static void     gtk_layout_allocate_child     (GtkLayout      *layout,
-                                              GtkLayoutChild *child);
-
-
-static void     gtk_layout_adjustment_changed (GtkAdjustment  *adjustment,
-                                              GtkLayout      *layout);
+enum {
+  CHILD_PROP_0,
+  CHILD_PROP_X,
+  CHILD_PROP_Y
+};
+
+static void gtk_layout_class_init         (GtkLayoutClass *class);
+static void gtk_layout_get_property       (GObject        *object,
+                                           guint           prop_id,
+                                           GValue         *value,
+                                           GParamSpec     *pspec);
+static void gtk_layout_set_property       (GObject        *object,
+                                           guint           prop_id,
+                                           const GValue   *value,
+                                           GParamSpec     *pspec);
+static void gtk_layout_init               (GtkLayout      *layout);
+static void gtk_layout_finalize           (GObject        *object);
+static void gtk_layout_realize            (GtkWidget      *widget);
+static void gtk_layout_unrealize          (GtkWidget      *widget);
+static void gtk_layout_map                (GtkWidget      *widget);
+static void gtk_layout_size_request       (GtkWidget      *widget,
+                                           GtkRequisition *requisition);
+static void gtk_layout_size_allocate      (GtkWidget      *widget,
+                                           GtkAllocation  *allocation);
+static gint gtk_layout_expose             (GtkWidget      *widget,
+                                           GdkEventExpose *event);
+static void gtk_layout_remove             (GtkContainer   *container,
+                                           GtkWidget      *widget);
+static void gtk_layout_forall             (GtkContainer   *container,
+                                           gboolean        include_internals,
+                                           GtkCallback     callback,
+                                           gpointer        callback_data);
+static void gtk_layout_set_adjustments    (GtkLayout      *layout,
+                                           GtkAdjustment  *hadj,
+                                           GtkAdjustment  *vadj);
+static void gtk_layout_set_child_property (GtkContainer   *container,
+                                           GtkWidget      *child,
+                                           guint           property_id,
+                                           const GValue   *value,
+                                           GParamSpec     *pspec);
+static void gtk_layout_get_child_property (GtkContainer   *container,
+                                           GtkWidget      *child,
+                                           guint           property_id,
+                                           GValue         *value,
+                                           GParamSpec     *pspec);
+static void gtk_layout_allocate_child     (GtkLayout      *layout,
+                                           GtkLayoutChild *child);
+static void gtk_layout_adjustment_changed (GtkAdjustment  *adjustment,
+                                           GtkLayout      *layout);
+
 
 static GtkWidgetClass *parent_class = NULL;
 
@@ -213,6 +225,26 @@ gtk_layout_set_vadjustment (GtkLayout     *layout,
   g_object_notify (G_OBJECT (layout), "vadjustment");
 }
 
+static GtkLayoutChild*
+get_child (GtkLayout  *layout,
+           GtkWidget  *widget)
+{
+  GList *children;
+  
+  children = layout->children;
+  while (children)
+    {
+      GtkLayoutChild *child;
+      
+      child = children->data;
+      children = children->next;
+
+      if (child->widget == widget)
+        return child;
+    }
+
+  return NULL;
+}
 
 void           
 gtk_layout_put (GtkLayout     *layout, 
@@ -235,38 +267,59 @@ gtk_layout_put (GtkLayout     *layout,
   
   if (GTK_WIDGET_REALIZED (layout))
     gtk_widget_set_parent_window (child->widget, layout->bin_window);
-  
+
   gtk_widget_set_parent (child_widget, GTK_WIDGET (layout));
 }
 
-void           
-gtk_layout_move (GtkLayout     *layout, 
-                GtkWidget     *child_widget, 
-                gint           x, 
-                gint           y)
+static void
+gtk_layout_move_internal (GtkLayout       *layout,
+                          GtkWidget       *widget,
+                          gboolean         change_x,
+                          gint             x,
+                          gboolean         change_y,
+                          gint             y)
 {
-  GList *tmp_list;
   GtkLayoutChild *child;
   
   g_return_if_fail (GTK_IS_LAYOUT (layout));
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (widget->parent == GTK_WIDGET (layout));  
+  
+  child = get_child (layout, widget);
 
-  tmp_list = layout->children;
-  while (tmp_list)
+  g_assert (child);
+
+  gtk_widget_freeze_child_notify (widget);
+  
+  if (change_x)
     {
-      child = tmp_list->data;
-      tmp_list = tmp_list->next;
+      child->x = x;
+      gtk_widget_child_notify (widget, "x");
+    }
 
-      if (child->widget == child_widget)
-       {
-         child->x = x;
-         child->y = y;
+  if (change_y)
+    {
+      child->y = y;
+      gtk_widget_child_notify (widget, "y");
+    }
+
+  gtk_widget_thaw_child_notify (widget);
+  
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (layout))
+    gtk_widget_queue_resize (GTK_WIDGET (layout));
+}
 
-         if (GTK_WIDGET_VISIBLE (child_widget) && GTK_WIDGET_VISIBLE (layout))
-           gtk_widget_queue_resize (child_widget);
+void           
+gtk_layout_move (GtkLayout     *layout, 
+                GtkWidget     *child_widget, 
+                gint           x, 
+                gint           y)
+{
+  g_return_if_fail (GTK_IS_LAYOUT (layout));
+  g_return_if_fail (GTK_IS_WIDGET (child_widget));
+  g_return_if_fail (child_widget->parent == GTK_WIDGET (layout));  
 
-         return;
-       }
-    }
+  gtk_layout_move_internal (layout, child_widget, TRUE, x, TRUE, y);
 }
 
 static void
@@ -413,6 +466,29 @@ gtk_layout_class_init (GtkLayoutClass *class)
   gobject_class->get_property = gtk_layout_get_property;
   gobject_class->finalize = gtk_layout_finalize;
 
+  container_class->set_child_property = gtk_layout_set_child_property;
+  container_class->get_child_property = gtk_layout_get_child_property;
+
+  gtk_container_class_install_child_property (container_class,
+                                             CHILD_PROP_X,
+                                             g_param_spec_int ("x",
+                                                                _("X position"),
+                                                                _("X position of child widget"),
+                                                                G_MININT,
+                                                                G_MAXINT,
+                                                                0,
+                                                                G_PARAM_READWRITE));
+
+  gtk_container_class_install_child_property (container_class,
+                                             CHILD_PROP_Y,
+                                             g_param_spec_int ("y",
+                                                                _("Y position"),
+                                                                _("Y position of child widget"),
+                                                                G_MININT,
+                                                                G_MAXINT,
+                                                                0,
+                                                                G_PARAM_READWRITE));
+  
   g_object_class_install_property (gobject_class,
                                   PROP_HADJUSTMENT,
                                   g_param_spec_object ("hadjustment",
@@ -528,6 +604,57 @@ gtk_layout_set_property (GObject      *object,
     }
 }
 
+static void
+gtk_layout_set_child_property (GtkContainer    *container,
+                               GtkWidget       *child,
+                               guint            property_id,
+                               const GValue    *value,
+                               GParamSpec      *pspec)
+{
+  switch (property_id)
+    {
+    case CHILD_PROP_X:
+      gtk_layout_move_internal (GTK_LAYOUT (container),
+                                child,
+                                TRUE, g_value_get_int (value),
+                                FALSE, 0);
+      break;
+    case CHILD_PROP_Y:
+      gtk_layout_move_internal (GTK_LAYOUT (container),
+                                child,
+                                FALSE, 0,
+                                TRUE, g_value_get_int (value));
+      break;
+    default:
+      GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_layout_get_child_property (GtkContainer *container,
+                               GtkWidget    *child,
+                               guint         property_id,
+                               GValue       *value,
+                               GParamSpec   *pspec)
+{
+  GtkLayoutChild *layout_child;
+
+  layout_child = get_child (GTK_LAYOUT (container), child);
+  
+  switch (property_id)
+    {
+    case CHILD_PROP_X:
+      g_value_set_int (value, layout_child->x);
+      break;
+    case CHILD_PROP_Y:
+      g_value_set_int (value, layout_child->y);
+      break;
+    default:
+      GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+      break;
+    }
+}
 
 static void
 gtk_layout_init (GtkLayout *layout)
index e27fd1f430059afc510877670db6752748dbbf2d..bb81a3acf97683da53e7bec6f19e3385595ed211 100644 (file)
@@ -156,7 +156,6 @@ gtk_plug_init (GtkPlug *plug)
   window = GTK_WINDOW (plug);
 
   window->type = GTK_WINDOW_TOPLEVEL;
-  window->auto_shrink = TRUE;
 }
 
 static void
index 12c4fc1293296a966db6eb7db671d011e227591e..7e6c457d41ff0c2c559bdae7283bfd349096e247 100644 (file)
@@ -121,10 +121,8 @@ enum {
   PROP_0,
   PROP_NAME,
   PROP_PARENT,
-  PROP_X,
-  PROP_Y,
-  PROP_WIDTH,
-  PROP_HEIGHT,
+  PROP_WIDTH_REQUEST,
+  PROP_HEIGHT_REQUEST,
   PROP_VISIBLE,
   PROP_SENSITIVE,
   PROP_APP_PAINTABLE,
@@ -213,7 +211,6 @@ static gint         gtk_widget_event_internal               (GtkWidget        *widget,
 static gboolean                gtk_widget_real_mnemonic_activate       (GtkWidget        *widget,
                                                                 gboolean          group_cycling);
 static void            gtk_widget_aux_info_destroy             (GtkWidgetAuxInfo *aux_info);
-static void            gtk_widget_do_uposition                 (GtkWidget        *widget);
 static AtkObject*      gtk_widget_real_get_accessible          (GtkWidget        *widget);
 static void            gtk_widget_accessible_interface_init    (AtkImplementorIface *iface);
 static AtkObject*      gtk_widget_ref_accessible               (AtkImplementor *implementor);
@@ -400,38 +397,21 @@ gtk_widget_class_init (GtkWidgetClass *klass)
                                                        _("The parent widget of this widget. Must be a Container widget."),
                                                        GTK_TYPE_CONTAINER,
                                                        G_PARAM_READWRITE));
+
   g_object_class_install_property (gobject_class,
-                                  PROP_X,
-                                  g_param_spec_int ("x",
-                                                    _("x coordinate"),
-                                                    _("The x coordinate of the top-left corner of the widget, or -1 if not set"),
-                                                    -G_MAXINT,
-                                                    G_MAXINT,
-                                                    -1,
-                                                    G_PARAM_READWRITE));
-  g_object_class_install_property (gobject_class,
-                                  PROP_Y,
-                                  g_param_spec_int ("y",
-                                                    _("y coordinate"),
-                                                    _("The y coordinate of the top-left corner of the widget, or -1 if not set"),
-                                                    -G_MAXINT,
-                                                    G_MAXINT,
-                                                    -1,
-                                                    G_PARAM_READWRITE));
-  g_object_class_install_property (gobject_class,
-                                  PROP_WIDTH,
-                                  g_param_spec_int ("width",
-                                                    _("Width"),
-                                                    _("The width of the widget, or -1 if unset."),
+                                  PROP_WIDTH_REQUEST,
+                                  g_param_spec_int ("width_request",
+                                                    _("Width request"),
+                                                    _("Override for width request of the widget, or -1 if natural request should be used."),
                                                     -1,
                                                     G_MAXINT,
                                                     -1,
                                                     G_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
-                                  PROP_HEIGHT,
-                                  g_param_spec_int ("height",
-                                                    _("Height"),
-                                                    _("The height of the widget, or -1 if unset."),
+                                  PROP_HEIGHT_REQUEST,
+                                  g_param_spec_int ("height_request",
+                                                    _("Height request"),
+                                                    _("Override for height request of the widget, or -1 if natural request should be used."),
                                                     -1,
                                                     G_MAXINT,
                                                     -1,
@@ -1078,7 +1058,6 @@ gtk_widget_set_property (GObject         *object,
                         GParamSpec      *pspec)
 {
   GtkWidget *widget;
-  GtkWidgetAuxInfo *aux_info;
 
   widget = GTK_WIDGET (object);
 
@@ -1092,32 +1071,10 @@ gtk_widget_set_property (GObject         *object,
     case PROP_PARENT:
       gtk_container_add (GTK_CONTAINER (g_value_get_object (value)), widget);
       break;
-    case PROP_X:
-      aux_info = _gtk_widget_get_aux_info (widget, TRUE);
-      if (g_value_get_int (value) == -1)
-       aux_info->x_set = FALSE;
-      else
-       {
-         aux_info->x_set = TRUE;
-         aux_info->x = g_value_get_int (value);
-       }
-      gtk_widget_do_uposition (widget);
-      break;
-    case PROP_Y:
-      aux_info = _gtk_widget_get_aux_info (widget, TRUE);
-      if (g_value_get_int (value) == -1)
-       aux_info->y_set = FALSE;
-      else
-       {
-         aux_info->y_set = TRUE;
-         aux_info->y = g_value_get_int (value);
-       }
-      gtk_widget_do_uposition (widget);
-      break;
-    case PROP_WIDTH:
+    case PROP_WIDTH_REQUEST:
       gtk_widget_set_usize (widget, g_value_get_int (value), -2);
       break;
-    case PROP_HEIGHT:
+    case PROP_HEIGHT_REQUEST:
       gtk_widget_set_usize (widget, -2, g_value_get_int (value));
       break;
     case PROP_VISIBLE:
@@ -1191,7 +1148,6 @@ gtk_widget_get_property (GObject         *object,
   
   switch (prop_id)
     {
-      GtkWidgetAuxInfo *aux_info;
       gint *eventp;
       GdkExtensionMode *modep;
 
@@ -1207,33 +1163,19 @@ gtk_widget_get_property (GObject         *object,
       else
        g_value_set_object (value, NULL);
       break;
-    case PROP_X:
-      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
-      if (!aux_info || !aux_info->x_set)
-       g_value_set_int (value, -1);
-      else
-       g_value_set_int (value, aux_info->x);
-      break;
-    case PROP_Y:
-      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
-      if (!aux_info || !aux_info->y_set)
-       g_value_set_int (value, -1);
-      else
-       g_value_set_int (value, aux_info->y);
-      break;
-    case PROP_WIDTH:
-      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
-      if (!aux_info)
-       g_value_set_int (value, -1);
-      else
-       g_value_set_int (value, aux_info->width);
+    case PROP_WIDTH_REQUEST:
+      {
+        int w;
+        gtk_widget_get_size_request (widget, &w, NULL);
+        g_value_set_int (value, w);
+      }
       break;
-    case PROP_HEIGHT:
-      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
-      if (!aux_info)
-       g_value_set_int (value, -1);
-      else
-       g_value_set_int (value, aux_info->height);
+    case PROP_HEIGHT_REQUEST:
+      {
+        int h;
+        gtk_widget_get_size_request (widget, NULL, &h);
+        g_value_set_int (value, h);
+      }
       break;
     case PROP_VISIBLE:
       g_value_set_boolean (value, (GTK_WIDGET_VISIBLE (widget) != FALSE));
@@ -2247,10 +2189,20 @@ gtk_widget_draw (GtkWidget    *widget,
  * @widget: a #GtkWidget
  * @requisition: a #GtkRequisition to be filled in
  * 
- * This function is only used when implementing a #GtkContainer subclass.
- * Obtains the preferred size of a widget. The container uses this
- * information to arrange its child widgets and decide what size allocations
- * to give them with gtk_widget_size_allocate().
+ * This function is typically used when implementing a #GtkContainer
+ * subclass.  Obtains the preferred size of a widget. The container
+ * uses this information to arrange its child widgets and decide what
+ * size allocations to give them with gtk_widget_size_allocate().
+ *
+ * You can also call this function from an application, with some
+ * caveats. Most notably, getting a size request requires the widget
+ * to be associated with a screen, because font information may be
+ * needed. Multihead-aware applications should keep this in mind.
+ *
+ * Also remember that the size request is not necessarily the size
+ * a widget will actually be allocated.
+ *
+ * See also gtk_widget_get_child_requisition().
  **/
 void
 gtk_widget_size_request (GtkWidget     *widget,
@@ -2282,6 +2234,19 @@ gtk_widget_size_request (GtkWidget       *widget,
  * @widget->requisition, unless someone has forced a particular
  * geometry on the widget (e.g. with gtk_widget_set_usize()), in which
  * case it returns that geometry instead of the widget's requisition.
+ *
+ * This function differs from gtk_widget_size_request() in that
+ * it retrieves the last size request value from widget->requisition,
+ * while gtk_widget_size_request() actually calls the "size_request" method
+ * on @widget to compute the size request and fill in widget->requisition,
+ * and only then returns widget->requisition.
+ *
+ * Because this function does not call the "size_request" method, it
+ * can only be used when you know that widget->requisition is
+ * up-to-date, that is, gtk_widget_size_request() has been called
+ * since the last time a resize was queued. In general, only container
+ * implementations have this information; applications should use
+ * gtk_widget_size_request().
  **/
 void
 gtk_widget_get_child_requisition (GtkWidget     *widget,
@@ -4306,28 +4271,6 @@ gtk_widget_child_focus (GtkWidget       *widget,
   return return_val;
 }
 
-/* Update the position from aux_info. Used from gtk_widget_set_uposition
- * and gtk_widget_set_property().
- */
-static void
-gtk_widget_do_uposition (GtkWidget *widget)
-{
-  GtkWidgetAuxInfo *aux_info =_gtk_widget_get_aux_info (widget, FALSE);
-
-  if (GTK_IS_WINDOW (widget) && aux_info->x_set && aux_info->y_set)
-    _gtk_window_reposition (GTK_WINDOW (widget), aux_info->x, aux_info->y);
-  
-  if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
-    gtk_widget_size_allocate (widget, &widget->allocation);
-
-  g_object_freeze_notify (G_OBJECT (widget));
-  if (aux_info->x_set)
-    g_object_notify (G_OBJECT (widget), "x");
-  if (aux_info->y_set)
-    g_object_notify (G_OBJECT (widget), "y");
-  g_object_thaw_notify (G_OBJECT (widget));
-}
-
 /**
  * gtk_widget_set_uposition:
  * @widget: a #GtkWidget
@@ -4356,6 +4299,11 @@ gtk_widget_set_uposition (GtkWidget *widget,
                          gint       x,
                          gint       y)
 {
+  /* FIXME this function is the only place that aux_info->x and
+   * aux_info->y are even used I believe, and this function is
+   * deprecated. Should be cleaned up.
+   */
+  
   GtkWidgetAuxInfo *aux_info;
   
   g_return_if_fail (GTK_IS_WIDGET (widget));
@@ -4384,7 +4332,11 @@ gtk_widget_set_uposition (GtkWidget *widget,
        }
     }
 
-  gtk_widget_do_uposition (widget);
+  if (GTK_IS_WINDOW (widget) && aux_info->x_set && aux_info->y_set)
+    _gtk_window_reposition (GTK_WINDOW (widget), aux_info->x, aux_info->y);
+  
+  if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
+    gtk_widget_size_allocate (widget, &widget->allocation);
 }
 
 /**
@@ -4393,6 +4345,9 @@ gtk_widget_set_uposition (GtkWidget *widget,
  * @width: minimum width, or -1 to unset
  * @height: minimum height, or -1 to unset
  *
+ * This function is deprecated; use gtk_widget_set_size_request()
+ * instead.
+ * 
  * Sets the minimum size of a widget; that is, the widget's size
  * request will be @width by @height. You can use this function to
  * force a widget to be either larger or smaller than it is. The
@@ -4427,12 +4382,12 @@ gtk_widget_set_usize (GtkWidget *widget,
   
   if (width > -2)
     {
-      g_object_notify (G_OBJECT (widget), "width");
+      g_object_notify (G_OBJECT (widget), "width_request");
       aux_info->width = width;
     }
   if (height > -2)
     {
-      g_object_notify (G_OBJECT (widget), "height");  
+      g_object_notify (G_OBJECT (widget), "height_request");  
       aux_info->height = height;
     }
   
@@ -4443,21 +4398,79 @@ gtk_widget_set_usize (GtkWidget *widget,
 }
 
 /**
- * gtk_widget_get_usize:
+ * gtk_widget_set_size_request:
+ * @widget: a #GtkWidget
+ * @width: width @widget should request, or -1 to unset
+ * @height: height @widget should request, or -1 to unset
+ *
+ * Sets the minimum size of a widget; that is, the widget's size
+ * request will be @width by @height. You can use this function to
+ * force a widget to be either larger or smaller than it normally
+ * would be.
+ *
+ * In most cases, gtk_window_set_default_size() is a better choice for
+ * toplevel windows than this function; setting the default size will
+ * still allow users to shrink the window. Setting the size request
+ * will force them to leave the window at least as large as the size
+ * request. When dealing with window sizes,
+ * gtk_window_set_geometry_hints() can be a useful function as well.
+ * 
+ * Note the inherent danger of setting any fixed size - themes,
+ * translations into other languages, different fonts, and user action
+ * can all change the appropriate size for a given widget. So, it's
+ * basically impossible to hardcode a size that will always be
+ * correct.
+ *
+ * The size request of a widget is the smallest size a widget can
+ * accept while still functioning well and drawing itself correctly.
+ * However in some strange cases a widget may be allocated less than
+ * its requested size, and in many cases a widget may be allocated more
+ * space than it requested.
+ *
+ * If the size request in a given direction is -1 (unset), then
+ * the "natural" size request of the widget will be used instead.
+ *
+ * Widgets can't actually be allocated a size less than 1 by 1, but
+ * you can pass 0,0 to this function to mean "as small as possible."
+ **/
+void
+gtk_widget_set_size_request (GtkWidget *widget,
+                             gint       width,
+                             gint       height)
+{
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (width >= -1);
+  g_return_if_fail (height >= -1);
+
+  if (width == 0)
+    width = 1;
+  if (height == 0)
+    height = 1;
+  
+  gtk_widget_set_usize (widget, width, height);
+}
+
+
+/**
+ * gtk_widget_get_size_request:
  * @widget: a #GtkWidget
- * @width: location to store the width, or %NULL
- * @height: location to store the height, or %NULL
+ * @width: return location for width, or %NULL
+ * @height: return location for height, or %NULL
  *
- * Gets the size that has explicitely set for the widget to request,
- * if any. A value of -1 stored in @width or @height indicates that
- * that dimension has not been set explicitely and the natural
- * requisition of the widget will be used intead. See
- * gtk_widget_set_usize().
+ * Gets the size request that was explicitly set for the widget using
+ * gtk_widget_set_size_request().  A value of -1 stored in @width or
+ * @height indicates that that dimension has not been set explicitly
+ * and the natural requisition of the widget will be used intead. See
+ * gtk_widget_set_size_request(). To get the size a widget will
+ * actually use, call gtk_widget_size_request() instead of
+ * this function.
+ * 
  **/
 void
-gtk_widget_get_usize (GtkWidget *widget,
-                     gint      *width,
-                     gint      *height)
+gtk_widget_get_size_request (GtkWidget *widget,
+                             gint      *width,
+                             gint      *height)
 {
   GtkWidgetAuxInfo *aux_info;
 
index fcd48c1ad8c70e00ff3f2b09cfe6ab848ebef99c..a6a7044e6afd5dc2a4a64f04b026d65bafd9acad 100644 (file)
@@ -562,6 +562,14 @@ GtkWidget *gtk_widget_get_parent          (GtkWidget           *widget);
 GdkWindow *gtk_widget_get_parent_window          (GtkWidget           *widget);
 gboolean   gtk_widget_child_focus         (GtkWidget           *widget,
                                            GtkDirectionType     direction);
+
+void       gtk_widget_set_size_request    (GtkWidget           *widget,
+                                           gint                 width,
+                                           gint                 height);
+void       gtk_widget_get_size_request    (GtkWidget           *widget,
+                                           gint                *width,
+                                           gint                *height);
+#ifndef GTK_DISABLE_DEPRECATED
 void      gtk_widget_set_uposition       (GtkWidget           *widget,
                                           gint                 x,
                                           gint                 y);
@@ -571,6 +579,8 @@ void           gtk_widget_set_usize           (GtkWidget           *widget,
 void       gtk_widget_get_usize           (GtkWidget           *widget,
                                           gint                *width,
                                           gint                *height);
+#endif
+
 void      gtk_widget_set_events          (GtkWidget           *widget,
                                           gint                 events);
 void       gtk_widget_add_events          (GtkWidget           *widget,
index e69a393b21fb19c904d208629a36c761dcae8713..e44efd42808a9e11ae14b0a1de79471406c418a6 100644 (file)
@@ -66,7 +66,6 @@ enum {
 
   /* Style Props */
   PROP_TITLE,
-  PROP_AUTO_SHRINK,
   PROP_ALLOW_SHRINK,
   PROP_ALLOW_GROW,
   PROP_RESIZABLE,
@@ -82,8 +81,7 @@ enum {
 typedef struct {
   GdkGeometry    geometry; /* Last set of geometry hints we set */
   GdkWindowHints flags;
-  gint           width;
-  gint           height;
+  GdkRectangle   configure_request;
 } GtkWindowLastGeometryInfo;
 
 struct _GtkWindowGeometryInfo
@@ -93,10 +91,30 @@ struct _GtkWindowGeometryInfo
   GdkGeometry    geometry;     /* Geometry hints */
   GdkWindowHints mask;
   GtkWidget     *widget;       /* subwidget to which hints apply */
-  gint           width;                /* Default size */
-  gint           height;
-  guint                 may_shrink : 1; /* one-shot auto_shrink behaviour after set_default_size */
+  /* from last gtk_window_resize () - if > 0, indicates that
+   * we should resize to this size.
+   */
+  gint           resize_width;  
+  gint           resize_height;
 
+  /* From last gtk_window_move () prior to mapping -
+   * only used if initial_pos_set
+   */
+  gint           initial_x;
+  gint           initial_y;
+  
+  /* Default size - used only the FIRST time we map a window,
+   * only if > 0.
+   */
+  gint           default_width; 
+  gint           default_height;
+  /* whether to use initial_x, initial_y */
+  guint          initial_pos_set : 1;
+  /* CENTER_ALWAYS or other position constraint changed since
+   * we sent the last configure request.
+   */
+  guint          position_constraints_changed : 1;
+  
   GtkWindowLastGeometryInfo last;
 };
 
@@ -153,31 +171,6 @@ static void gtk_window_real_activate_default (GtkWindow         *window);
 static void gtk_window_real_activate_focus   (GtkWindow         *window);
 static void gtk_window_move_focus            (GtkWindow         *window,
                                               GtkDirectionType   dir);
-
-static void gtk_window_move_resize        (GtkWindow         *window);
-static gboolean gtk_window_compare_hints  (GdkGeometry       *geometry_a,
-                                          guint              flags_a,
-                                          GdkGeometry       *geometry_b,
-                                          guint              flags_b);
-static void gtk_window_compute_default_size (GtkWindow       *window,
-                                            guint           *width,
-                                            guint           *height);
-static void  gtk_window_constrain_size      (GtkWindow       *window,
-                                            GdkGeometry     *geometry,
-                                            guint            flags,
-                                            gint             width,
-                                            gint             height,
-                                            gint            *new_width,
-                                            gint            *new_height);
-static void gtk_window_compute_hints      (GtkWindow         *window, 
-                                          GdkGeometry       *new_geometry,
-                                          guint             *new_flags);
-static gint gtk_window_compute_reposition (GtkWindow         *window,
-                                          gint               new_width,
-                                          gint               new_height,
-                                          gint              *x,
-                                          gint              *y);
-
 static void gtk_window_read_rcfiles       (GtkWidget         *widget,
                                           GdkEventClient    *event);
 static void gtk_window_paint              (GtkWidget         *widget,
@@ -190,8 +183,39 @@ static void gtk_window_transient_parent_realized   (GtkWidget  *parent,
 static void gtk_window_transient_parent_unrealized (GtkWidget  *parent,
                                                    GtkWidget  *window);
 
-static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
-                                                           gboolean   create);
+static GtkWindowGeometryInfo* gtk_window_get_geometry_info         (GtkWindow    *window,
+                                                                    gboolean      create);
+
+static void     gtk_window_move_resize               (GtkWindow    *window);
+static gboolean gtk_window_compare_hints             (GdkGeometry  *geometry_a,
+                                                      guint         flags_a,
+                                                      GdkGeometry  *geometry_b,
+                                                      guint         flags_b);
+static void     gtk_window_constrain_size            (GtkWindow    *window,
+                                                      GdkGeometry  *geometry,
+                                                      guint         flags,
+                                                      gint          width,
+                                                      gint          height,
+                                                      gint         *new_width,
+                                                      gint         *new_height);
+static void     gtk_window_constrain_position        (GtkWindow    *window,
+                                                      gint          new_width,
+                                                      gint          new_height,
+                                                      gint         *x,
+                                                      gint         *y);
+static void     gtk_window_compute_hints             (GtkWindow    *window,
+                                                      GdkGeometry  *new_geometry,
+                                                      guint        *new_flags);
+static void     gtk_window_compute_configure_request (GtkWindow    *window,
+                                                      GdkRectangle *request,
+                                                      GdkGeometry  *geometry,
+                                                      guint        *flags);
+
+static void     gtk_window_set_default_size_internal (GtkWindow    *window,
+                                                      gboolean      change_width,
+                                                      gint          width,
+                                                      gboolean      change_height,
+                                                      gint          height);
 
 
 static GSList      *toplevel_list = NULL;
@@ -334,19 +358,11 @@ gtk_window_class_init (GtkWindowClass *klass)
                                                         NULL,
                                                         G_PARAM_READWRITE));
 
-  g_object_class_install_property (gobject_class,
-                                   PROP_AUTO_SHRINK,
-                                   g_param_spec_boolean ("auto_shrink",
-                                                        _("Auto Shrink"),
-                                                        _("If TRUE, the window automatically shrinks to its size request anytime a resize occurs. Don't use this feature, it makes no sense."),
-                                                        FALSE,
-                                                        G_PARAM_READWRITE));
-
   g_object_class_install_property (gobject_class,
                                    PROP_ALLOW_SHRINK,
                                    g_param_spec_boolean ("allow_shrink",
                                                         _("Allow Shrink"),
-                                                        _("If TRUE, the window has no mimimum size. Don't use this feature, it makes no sense."),
+                                                        _("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea."),
                                                         FALSE,
                                                         G_PARAM_READWRITE));
 
@@ -387,22 +403,22 @@ gtk_window_class_init (GtkWindowClass *klass)
                                    PROP_DEFAULT_WIDTH,
                                    g_param_spec_int ("default_width",
                                                     _("Default Width"),
-                                                    _("The default width of the window, or 0 to use the size request."),
-                                                    0,
+                                                    _("The default width of the window, used when initially showing the window."),
+                                                    -1,
                                                     G_MAXINT,
-                                                    0,
+                                                    -1,
                                                     G_PARAM_READWRITE));
+  
   g_object_class_install_property (gobject_class,
                                    PROP_DEFAULT_HEIGHT,
                                    g_param_spec_int ("default_height",
                                                     _("Default Height"),
-                                                    _("The default height of the window, or 0 to use the size request."),
-                                                    0,
+                                                    _("The default height of the window, used when initially showing the window."),
+                                                    -1,
                                                     G_MAXINT,
-                                                    0,
+                                                    -1,
                                                     G_PARAM_READWRITE));
+  
   g_object_class_install_property (gobject_class,
                                    PROP_DESTROY_WITH_PARENT,
                                    g_param_spec_boolean ("destroy_with_parent",
@@ -552,13 +568,13 @@ gtk_window_init (GtkWindow *window)
   window->type = GTK_WINDOW_TOPLEVEL;
   window->focus_widget = NULL;
   window->default_widget = NULL;
-  window->resize_count = 0;
+  window->configure_request_count = 0;
   window->allow_shrink = FALSE;
   window->allow_grow = TRUE;
-  window->auto_shrink = FALSE;
-  window->handling_resize = FALSE;
+  window->configure_notify_received = FALSE;
   window->position = GTK_WIN_POS_NONE;
-  window->use_uposition = TRUE;
+  window->need_default_size = TRUE;
+  window->need_default_position = TRUE;
   window->modal = FALSE;
   window->frame = NULL;
   window->has_frame = FALSE;
@@ -591,7 +607,7 @@ gtk_window_set_property (GObject      *object,
                         GParamSpec   *pspec)
 {
   GtkWindow  *window;
-
+  
   window = GTK_WINDOW (object);
 
   switch (prop_id)
@@ -602,10 +618,6 @@ gtk_window_set_property (GObject      *object,
     case PROP_TITLE:
       gtk_window_set_title (window, g_value_get_string (value));
       break;
-    case PROP_AUTO_SHRINK:
-      window->auto_shrink = g_value_get_boolean (value);
-      gtk_widget_queue_resize (GTK_WIDGET (window));
-      break;
     case PROP_ALLOW_SHRINK:
       window->allow_shrink = g_value_get_boolean (value);
       gtk_widget_queue_resize (GTK_WIDGET (window));
@@ -627,10 +639,14 @@ gtk_window_set_property (GObject      *object,
       gtk_window_set_position (window, g_value_get_enum (value));
       break;
     case PROP_DEFAULT_WIDTH:
-      gtk_window_set_default_size (window, g_value_get_int (value), -1);
+      gtk_window_set_default_size_internal (window,
+                                            TRUE, g_value_get_int (value),
+                                            FALSE, -1);
       break;
     case PROP_DEFAULT_HEIGHT:
-      gtk_window_set_default_size (window, -1, g_value_get_int (value));
+      gtk_window_set_default_size_internal (window,
+                                            FALSE, -1,
+                                            TRUE, g_value_get_int (value));
       break;
     case PROP_DESTROY_WITH_PARENT:
       gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
@@ -659,9 +675,6 @@ gtk_window_get_property (GObject      *object,
     case PROP_TITLE:
       g_value_set_string (value, window->title);
       break;
-    case PROP_AUTO_SHRINK:
-      g_value_set_boolean (value, window->auto_shrink);
-      break;
     case PROP_ALLOW_SHRINK:
       g_value_set_boolean (value, window->allow_shrink);
       break;
@@ -680,16 +693,16 @@ gtk_window_get_property (GObject      *object,
     case PROP_DEFAULT_WIDTH:
       info = gtk_window_get_geometry_info (window, FALSE);
       if (!info)
-       g_value_set_int (value, 0);
+       g_value_set_int (value, -1);
       else
-       g_value_set_int (value, info->width);
+       g_value_set_int (value, info->default_width);
       break;
     case PROP_DEFAULT_HEIGHT:
       info = gtk_window_get_geometry_info (window, FALSE);
       if (!info)
-       g_value_set_int (value, 0);
+       g_value_set_int (value, -1);
       else
-       g_value_set_int (value, info->height);
+       g_value_set_int (value, info->default_height);
       break;
     case PROP_DESTROY_WITH_PARENT:
       g_value_set_boolean (value, window->destroy_with_parent);
@@ -950,12 +963,10 @@ gtk_window_set_policy (GtkWindow *window,
 
   window->allow_shrink = (allow_shrink != FALSE);
   window->allow_grow = (allow_grow != FALSE);
-  window->auto_shrink = (auto_shrink != FALSE);
 
   g_object_notify (G_OBJECT (window), "allow_shrink");
   g_object_notify (G_OBJECT (window), "allow_grow");
   g_object_notify (G_OBJECT (window), "resizable");
-  g_object_notify (G_OBJECT (window), "auto_shrink");
   
   gtk_widget_queue_resize (GTK_WIDGET (window));
 }
@@ -1125,8 +1136,24 @@ gtk_window_set_position (GtkWindow         *window,
 {
   g_return_if_fail (GTK_IS_WINDOW (window));
 
-  window->position = position;
+  if (position == GTK_WIN_POS_CENTER_ALWAYS ||
+      window->position == GTK_WIN_POS_CENTER_ALWAYS)
+    {
+      GtkWindowGeometryInfo *info;
 
+      info = gtk_window_get_geometry_info (window, TRUE);
+
+      /* this flag causes us to re-request the CENTER_ALWAYS
+       * constraint in gtk_window_move_resize(), see
+       * comment in that function.
+       */
+      info->position_constraints_changed = TRUE;
+
+      gtk_widget_queue_resize (GTK_WIDGET (window));
+    }
+
+  window->position = position;
+  
   g_object_notify (G_OBJECT (window), "window_position");
 }
 
@@ -1293,25 +1320,7 @@ _gtk_window_reposition (GtkWindow *window,
   
   g_return_if_fail (GTK_IS_WINDOW (window));
 
-  /* keep this in sync with gtk_window_compute_reposition()
-   */
-  if (GTK_WIDGET_REALIZED (window))
-    {
-      info = gtk_window_get_geometry_info (window, TRUE);
-
-      if (!(info->last.flags & GDK_HINT_POS))
-       {
-         info->last.flags |= GDK_HINT_POS;
-         gdk_window_set_geometry_hints (GTK_WIDGET (window)->window,
-                                        &info->last.geometry,
-                                        info->last.flags);
-       }
-
-      if (window->frame)
-       gdk_window_move (window->frame,  x - window->frame_left, y - window->frame_top);
-      else
-       gdk_window_move (GTK_WIDGET (window)->window, x, y);
-    }
+  gtk_window_move (window, x, y);
 }
 
 static void
@@ -1573,13 +1582,20 @@ gtk_window_get_geometry_info (GtkWindow *window,
     {
       info = g_new0 (GtkWindowGeometryInfo, 1);
 
-      info->width = 0;
-      info->height = 0;
-      info->last.width = -1;
-      info->last.height = -1;
+      info->default_width = -1;
+      info->default_height = -1;
+      info->resize_width = -1;
+      info->resize_height = -1;
+      info->initial_x = 0;
+      info->initial_y = 0;
+      info->initial_pos_set = FALSE;
+      info->position_constraints_changed = FALSE;
+      info->last.configure_request.x = 0;
+      info->last.configure_request.y = 0;
+      info->last.configure_request.width = -1;
+      info->last.configure_request.height = -1;
       info->widget = NULL;
       info->mask = 0;
-      info->may_shrink = FALSE;
       window->geometry_info = info;
     }
 
@@ -1625,8 +1641,14 @@ gtk_window_set_geometry_hints (GtkWindow       *window,
   if (geometry)
     info->geometry = *geometry;
 
-  info->mask = geom_mask;
+  /* We store gravity in window->gravity not in the hints. */
+  info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
 
+  if (geom_mask & GDK_HINT_WIN_GRAVITY)
+    {
+      gtk_window_set_gravity (window, geometry->win_gravity);
+    }
+  
   gtk_widget_queue_resize (GTK_WIDGET (window));
 }
 
@@ -1683,21 +1705,73 @@ gtk_window_get_decorated (GtkWindow *window)
   return window->decorated;
 }
 
+static void
+gtk_window_set_default_size_internal (GtkWindow    *window,
+                                      gboolean      change_width,
+                                      gint          width,
+                                      gboolean      change_height,
+                                      gint          height)
+{
+  GtkWindowGeometryInfo *info;
+
+  g_return_if_fail (GTK_IS_WINDOW (window));
+  g_return_if_fail (change_width == FALSE || width >= -1);
+  g_return_if_fail (change_height == FALSE || height >= -1);
+
+  info = gtk_window_get_geometry_info (window, TRUE);
+
+  g_object_freeze_notify (G_OBJECT (window));
+
+  if (change_width)
+    {
+      if (width == 0)
+        width = 1;
+
+      if (width < 0)
+        width = -1;
+
+      info->default_width = width;
+
+      g_object_notify (G_OBJECT (window), "default_width");
+    }
+
+  if (change_height)
+    {
+      if (height == 0)
+        height = 1;
+
+      if (height < 0)
+        height = -1;
+
+      info->default_height = height;
+      
+      g_object_notify (G_OBJECT (window), "default_height");
+    }
+  
+  g_object_thaw_notify (G_OBJECT (window));
+  
+  gtk_widget_queue_resize (GTK_WIDGET (window));
+}
+
 /**
  * gtk_window_set_default_size:
  * @window: a #GtkWindow
- * @width: width in pixels, 0 to unset, or -1 to leave the width unchanged
- * @height: height in pixels, 0 to unset, or -1 to leave the height unchanged
+ * @width: width in pixels, or -1 to unset the default width
+ * @height: height in pixels, or -1 to unset the default height
  *
  * Sets the default size of a window. If the window's "natural" size
  * (its size request) is larger than the default, the default will be
- * ignored. So the default size is a minimum initial size.  Unlike
- * gtk_widget_set_usize(), which sets a size request for a widget and
- * thus would keep users from shrinking the window, this function only
- * sets the initial size, just as if the user had resized the window
- * themselves. Users can still shrink the window again as they
- * normally would. Setting a default size of 0 means to use the
- * "natural" default size (the size request of the window).
+ * ignored. More generally, if the default size does not obey the
+ * geometry hints for the window (gtk_window_set_geometry_hints() can
+ * be used to set these explicitly), the default size will be clamped
+ * to the nearest permitted size.
+ * 
+ * Unlike gtk_widget_set_size_request(), which sets a size request for
+ * a widget and thus would keep users from shrinking the window, this
+ * function only sets the initial size, just as if the user had
+ * resized the window themselves. Users can still shrink the window
+ * again as they normally would. Setting a default size of -1 means to
+ * use the "natural" default size (the size request of the window).
  *
  * For more control over a window's initial size and how resizing works,
  * investigate gtk_window_set_geometry_hints().
@@ -1706,35 +1780,29 @@ gtk_window_get_decorated (GtkWindow *window)
  * gtk_window_set_geometry_hints(), the default size specified by
  * gtk_window_set_default_size() will be the default size of that
  * widget, not of the entire window.
- * 
+ *
+ * For some uses, gtk_window_resize() is a more appropriate function.
+ * gtk_window_resize() changes the current size of the window, rather
+ * than the size to be used on initial display. gtk_window_resize() always
+ * affects the window itself, not the geometry widget.
+ *
+ * The default size of a window only affects the first time a window is
+ * shown; if a window is hidden and re-shown, it will remember the size
+ * it had prior to hiding, rather than using the default size.
+ *
+ * Windows can't actually be 0x0 in size, they must be at least 1x1, but
+ * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
  **/
 void       
 gtk_window_set_default_size (GtkWindow   *window,
                             gint         width,
                             gint         height)
 {
-  GtkWindowGeometryInfo *info;
-
   g_return_if_fail (GTK_IS_WINDOW (window));
+  g_return_if_fail (width >= -1);
+  g_return_if_fail (height >= -1);
 
-  info = gtk_window_get_geometry_info (window, TRUE);
-
-  g_object_freeze_notify (G_OBJECT (window));
-  if (width >= 0)
-    {
-      info->width = width;
-      g_object_notify (G_OBJECT (window), "default_width");
-      info->may_shrink = TRUE;
-    }
-  if (height >= 0)
-    {
-      info->height = height;
-      g_object_notify (G_OBJECT (window), "default_height");
-      info->may_shrink = TRUE;
-    }
-  g_object_thaw_notify (G_OBJECT (window));
-  
-  gtk_widget_queue_resize (GTK_WIDGET (window));
+  gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height);
 }
 
 /**
@@ -1743,10 +1811,11 @@ gtk_window_set_default_size (GtkWindow   *window,
  * @width: location to store the default width, or %NULL
  * @height: location to store the default height, or %NULL
  *
- * Gets the default size of the window. A value of 0 for the
- * width or height indicates that a default size has not
- * been explicitely set for that dimension, so the value
- * will be computed from the requisition of the window.
+ * Gets the default size of the window. A value of -1 for the width or
+ * height indicates that a default size has not been explicitly set
+ * for that dimension, so the "natural" size of the window will be
+ * used.
+ * 
  **/
 void
 gtk_window_get_default_size (GtkWindow *window,
@@ -1760,12 +1829,425 @@ gtk_window_get_default_size (GtkWindow *window,
   info = gtk_window_get_geometry_info (window, FALSE);
 
   if (width)
-    *width = info ? info->width : 0;
+    *width = info->default_width;
+
+  if (height)
+    *height = info->default_height;
+}
+
+/**
+ * gtk_window_resize:
+ * @window: a #GtkWindow
+ * @width: width to resize the window to
+ * @height: height to resize the window to
+ *
+ * Resizes the window as if the user had done so, obeying geometry
+ * constraints. The default geometry constraint is that windows may
+ * not be smaller than their size request; to override this
+ * constraint, call gtk_widget_set_size_request() to set the window's
+ * request to a smaller value.
+ *
+ * If gtk_window_resize() is called before showing a window for the
+ * first time, it overrides any default size set with
+ * gtk_window_set_default_size().
+ *
+ * Windows may not be resized smaller than 1 by 1 pixels.
+ * 
+ **/
+void
+gtk_window_resize (GtkWindow *window,
+                   gint       width,
+                   gint       height)
+{
+  GtkWindowGeometryInfo *info;
+  
+  g_return_if_fail (GTK_IS_WINDOW (window));
+  g_return_if_fail (width > 0);
+  g_return_if_fail (height > 0);
+
+  info = gtk_window_get_geometry_info (window, TRUE);
+
+  info->resize_width = width;
+  info->resize_height = height;
+
+  gtk_widget_queue_resize (GTK_WIDGET (window));
+}
+
+/**
+ * gtk_window_get_size:
+ * @window: a #GtkWindow
+ * @width: return location for width, or %NULL
+ * @height: return location for height, or %NULL
+ *
+ * Obtains the current size of @window. If @window is not onscreen,
+ * returns the size GTK+ will suggest to the window manager for the
+ * initial window size (but this is not reliably the same as the size
+ * the window manager will actually select). The size obtained by
+ * gtk_window_get_size() is the last size received in a
+ * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
+ * rather than querying the X server for the size. As a result, if you
+ * call gtk_window_resize() then immediately call
+ * gtk_window_get_size(), the size won't have taken effect yet. After
+ * the window manager processes the resize request, GTK+ receives
+ * notification that the size has changed via a configure event, and
+ * the size of the window gets updated.
+ *
+ * Note #1: Nearly any use of this function creates a race condition,
+ * because the size of the window may change between the time that you
+ * get the size and the time that you perform some action assuming
+ * that size is the current size. To avoid race conditions, connect to
+ * "configure_event" on the window and adjust your size-dependent
+ * state to match the size delivered in the #GdkEventConfigure.
+ *
+ * Note #2: The returned size does NOT include the size of the window
+ * manager decorations (aka the window frame or border). Those
+ * are not drawn by GTK+ and GTK+ has no reliable method of
+ * determining their size.
+ *
+ * Note #3: If you are getting a window size in order to position
+ * the window onscreen, there may be a better way. The preferred
+ * way is to simply set the window's semantic type with
+ * gtk_window_set_type_hint(), which allows the window manager to
+ * e.g. center dialogs. Also, if you set the transient parent of
+ * dialogs with gtk_widget_set_transient_for() window managers
+ * will often center the dialog over its parent window. It's
+ * much preferred to let the window manager handle these
+ * things rather than doing it yourself, because all apps will
+ * behave consistently and according to user prefs if the window
+ * manager handles it. Also, the window manager can take the size
+ * of the window decorations/border into account, while your
+ * application cannot.
+ *
+ * In any case, if you insist on application-specified window
+ * positioning, there's STILL a better way than doing it yourself -
+ * gtk_window_set_position() will frequently handle the details
+ * for you.
+ * 
+ **/
+void
+gtk_window_get_size (GtkWindow *window,
+                     gint      *width,
+                     gint      *height)
+{
+  gint w, h;
+  GtkWidget *widget;
+  
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  widget = GTK_WIDGET (window);
+  
+  if (width == NULL && height == NULL)
+    return;
+
+  if (GTK_WIDGET_MAPPED (window))
+    {
+      gdk_drawable_get_size (GTK_WIDGET (window)->window,
+                             &w, &h);
+    }
+  else
+    {
+      GdkRectangle configure_request;
 
+      gtk_window_compute_configure_request (window,
+                                            &configure_request,
+                                            NULL, NULL);
+
+      w = configure_request.width;
+      h = configure_request.height;
+    }
+  
+  if (width)
+    *width = w;
   if (height)
-    *height = info ? info->height : 0;
+    *height = h;
+}
+
+/**
+ * gtk_window_move:
+ * @window: a #GtkWindow
+ * @x: X coordinate to move window to
+ * @y: Y coordinate to move window to
+ *
+ * Asks the window manager to move @window to the given position.
+ * Window managers are free to ignore this; most window managers
+ * ignore requests for initial window positions (instead using a
+ * user-defined placement algorithm) and honor requests after the
+ * window has already been shown.
+ *
+ * Note: the position is the position of the gravity-determined
+ * reference point for the window. The gravity determines two things:
+ * first, the location of the reference point in root window
+ * coordinates; and second, which point on the window is positioned at
+ * the reference point.
+ *
+ * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
+ * point is simply the @x, @y supplied to gtk_window_move(). The
+ * top-left corner of the window decorations (aka window frame or
+ * border) will be placed at @x, @y.  Therefore, to position a window
+ * at the top left of the screen, you want to use the default gravity
+ * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
+ *
+ * To position a window at the bottom right corner of the screen, you
+ * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
+ * point is at @x + the window width and @y + the window height, and
+ * the bottom-right corner of the window border will be placed at that
+ * reference point. So, to place a window in the bottom right corner
+ * you would first set gravity to south east, then write:
+ * gtk_window_move (window, gdk_screen_width () - window_width,
+ * gdk_screen_height () - window_height).
+ *
+ * The extended window manager hints specification at
+ * http://www.freedesktop.org/standards/wm-spec.html has a nice table
+ * of gravities in the "implementation notes" section.
+ *
+ * The gtk_window_get_position() documentation may also be relevant.
+ * 
+ **/
+void
+gtk_window_move (GtkWindow *window,
+                 gint       x,
+                 gint       y)
+{
+  GtkWindowGeometryInfo *info;
+  GtkWidget *widget;
+  
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  widget = GTK_WIDGET (window);
+
+  info = gtk_window_get_geometry_info (window, TRUE);  
+  
+  if (GTK_WIDGET_MAPPED (window))
+    {
+      /* we have now sent a request with this position
+       * with currently-active constraints, so toggle flag.
+       */
+      info->position_constraints_changed = FALSE;
+
+      /* we only constrain if mapped - if not mapped,
+       * then gtk_window_compute_configure_request()
+       * will apply the constraints later, and we
+       * don't want to lose information about
+       * what position the user set before then.
+       * i.e. if you do a move() then turn off POS_CENTER
+       * then show the window, your move() will work.
+       */
+      gtk_window_constrain_position (window,
+                                     widget->allocation.width,
+                                     widget->allocation.height,
+                                     &x, &y);
+      
+      /* Note that this request doesn't go through our standard request
+       * framework, e.g. doesn't increment configure_request_count,
+       * doesn't set info->last, etc.; that's because
+       * we don't save the info needed to arrive at this same request
+       * again.
+       *
+       * To gtk_window_move_resize(), this will end up looking exactly
+       * the same as the position being changed by the window
+       * manager.
+       */
+      
+      /* FIXME are we handling gravity properly for framed windows? */
+      if (window->frame)
+        gdk_window_move (window->frame,
+                         x - window->frame_left,
+                         y - window->frame_top);
+      else
+        gdk_window_move (GTK_WIDGET (window)->window,
+                         x, y);
+    }
+  else
+    {
+      /* Save this position to apply on mapping */
+      info->initial_x = x;
+      info->initial_y = y;
+      info->initial_pos_set = TRUE;
+    }
+}
+
+/**
+ * gtk_window_get_position:
+ * @window: a #GtkWindow
+ * @root_x: return location for X coordinate of gravity-determined reference p\oint
+ * @root_y: return location for Y coordinate of gravity-determined reference p\oint
+ *
+ * This function returns the position you need to pass to
+ * gtk_window_move() to keep @window in its current position.  This
+ * means that the meaning of the returned value varies with window
+ * gravity. See gtk_window_move() for more details.
+ * 
+ * If you haven't changed the window gravity, its gravity will be
+ * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
+ * returns the position of the top-left corner of the window
+ * manager frame for the window. gtk_window_move() sets the
+ * position of this same top-left corner.
+ *
+ * gtk_window_get_position() is not 100% reliable because the X Window System
+ * does not specify a way to obtain the geometry of the
+ * decorations placed on a window by the window manager.
+ * Thus GTK+ is using a "best guess" that works with most
+ * window managers.
+ *
+ * Moreover, nearly all window managers are broken with respect to
+ * their handling of window gravity. So moving a window to its current
+ * position as returned by gtk_window_get_position() tends to
+ * result in moving the window slightly.
+ *
+ * If a window has gravity #GDK_GRAVITY_STATIC the window manager
+ * frame is not relevant, and thus gtk_window_get_position() will
+ * always produce accurate results. However you can't use static
+ * gravity to do things like place a window in a corner of the screen,
+ * because static gravity ignores the window manager decorations.
+ *
+ * If you are saving and restoring your application's window
+ * positions, you should know that it's impossible for applications to
+ * do this without getting it somewhat wrong because applications do
+ * not have sufficient knowledge of window manager state. The Correct
+ * Mechanism is to support the session management protocol (see the
+ * "GnomeClient" object in the GNOME libraries for example) and allow
+ * the window manager to save your window sizes and positions.
+ * 
+ **/
+
+void
+gtk_window_get_position (GtkWindow *window,
+                         gint      *root_x,
+                         gint      *root_y)
+{
+  GtkWidget *widget;
+
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  widget = GTK_WIDGET (window);
+  
+  if (window->gravity == GDK_GRAVITY_STATIC)
+    {
+      if (GTK_WIDGET_MAPPED (widget))
+        {
+          /* This does a server round-trip, which is sort of wrong;
+           * but a server round-trip is inevitable for
+           * gdk_window_get_frame_extents() in the usual
+           * NorthWestGravity case below, so not sure what else to
+           * do. We should likely be consistent about whether we get
+           * the client-side info or the server-side info.
+           */
+          gdk_window_get_origin (widget->window, root_x, root_y);
+        }
+      else
+        {
+          GdkRectangle configure_request;
+          
+          gtk_window_compute_configure_request (window,
+                                                &configure_request,
+                                                NULL, NULL);
+          
+          *root_x = configure_request.x;
+          *root_y = configure_request.y;
+        }
+    }
+  else
+    {
+      GdkRectangle frame_extents;
+      
+      gint x, y;
+      gint w, h;
+      
+      if (GTK_WIDGET_MAPPED (widget))
+        {
+          gdk_window_get_frame_extents (widget->window, &frame_extents);
+          x = frame_extents.x;
+          y = frame_extents.y;
+          gtk_window_get_size (window, &w, &h);
+        }
+      else
+        {
+          /* We just say the frame has 0 size on all sides.
+           * Not sure what else to do.
+           */             
+          gtk_window_compute_configure_request (window,
+                                                &frame_extents,
+                                                NULL, NULL);
+          x = frame_extents.x;
+          y = frame_extents.y;
+          w = frame_extents.width;
+          h = frame_extents.height;
+        }
+      
+      switch (window->gravity)
+        {
+        case GDK_GRAVITY_NORTH:
+        case GDK_GRAVITY_CENTER:
+        case GDK_GRAVITY_SOUTH:
+          /* Find center of frame. */
+          x += frame_extents.width / 2;
+          /* Center client window on that point. */
+          x -= w / 2;
+          break;
+
+        case GDK_GRAVITY_SOUTH_EAST:
+        case GDK_GRAVITY_EAST:
+        case GDK_GRAVITY_NORTH_EAST:
+          /* Find right edge of frame */
+          x += frame_extents.width;
+          /* Align left edge of client at that point. */
+          x -= w;
+          break;
+        default:
+          break;
+        }
+
+      switch (window->gravity)
+        {
+        case GDK_GRAVITY_WEST:
+        case GDK_GRAVITY_CENTER:
+        case GDK_GRAVITY_EAST:
+          /* Find center of frame. */
+          y += frame_extents.height / 2;
+          /* Center client window there. */
+          y -= h / 2;
+          break;
+        case GDK_GRAVITY_SOUTH_WEST:
+        case GDK_GRAVITY_SOUTH:
+        case GDK_GRAVITY_SOUTH_EAST:
+          /* Find south edge of frame */
+          y += frame_extents.height;
+          /* Place bottom edge of client there */
+          y -= h;
+          break;
+        default:
+          break;
+        }
+      
+      if (root_x)
+        *root_x = x;
+      if (root_y)
+        *root_y = y;
+    }
 }
+
+/**
+ * gtk_window_reshow_with_initial_size:
+ * @window: a #GtkWindow
+ * 
+ * Hides @window, then reshows it, resetting the
+ * default size and position of the window. Used
+ * by GUI builders only.
+ **/
+void
+gtk_window_reshow_with_initial_size (GtkWindow *window)
+{
+  GtkWidget *widget;
+  
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  widget = GTK_WIDGET (window);
   
+  gtk_widget_hide (widget);
+  gtk_widget_unrealize (widget);
+  gtk_widget_show (widget);
+}
+
 static void
 gtk_window_destroy (GtkObject *object)
 {
@@ -1863,44 +2345,56 @@ gtk_window_show (GtkWidget *widget)
     {
       GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
       GtkAllocation allocation = { 0, 0 };
+      GdkRectangle configure_request;
       GdkGeometry new_geometry;
-      guint width, height, new_flags;
+      guint new_flags;
       gboolean was_realized;
-      
-      /* determine default size to initially show the window with */
-      gtk_widget_size_request (widget, NULL);
-      gtk_window_compute_default_size (window, &width, &height);
-      
-      /* save away the last default size for later comparisions */
-      info->last.width = width;
-      info->last.height = height;
 
-      /* constrain size to geometry */
-      gtk_window_compute_hints (window, &new_geometry, &new_flags);
-      gtk_window_constrain_size (window,
-                                &new_geometry, new_flags,
-                                width, height,
-                                &width, &height);
+      /* We are going to go ahead and perform this configure request
+       * and then emulate a configure notify by going ahead and
+       * doing a size allocate. Sort of a synchronous
+       * mini-copy of gtk_window_move_resize() here.
+       */
+      gtk_window_compute_configure_request (window,
+                                            &configure_request,
+                                            &new_geometry,
+                                            &new_flags);
       
-      /* and allocate the window */
-      allocation.width  = width;
-      allocation.height = height;
-      gtk_widget_size_allocate (widget, &allocation);
+      /* We update this because we are going to go ahead
+       * and gdk_window_resize() below, rather than
+       * queuing it.
+       */
+      info->last.configure_request.width = configure_request.width;
+      info->last.configure_request.height = configure_request.height;
       
+      /* and allocate the window - this is normally done
+       * in move_resize in response to configure notify
+       */
+      allocation.width  = configure_request.width;
+      allocation.height = configure_request.height;
+      gtk_widget_size_allocate (widget, &allocation);
+
+      /* Then we guarantee we have a realize */
       was_realized = FALSE;
       if (!GTK_WIDGET_REALIZED (widget))
        {
          gtk_widget_realize (widget);
-         was_realized = TRUE;;
+         was_realized = TRUE;
        }
 
       /* Must be done after the windows are realized,
        * so that the decorations can be read
        */
       gtk_decorated_window_calculate_frame_size (window);
-      
+
+      /* We only send configure request if we didn't just finish
+       * creating the window; if we just created the window
+       * then we created it with widget->allocation anyhow.
+       */
       if (!was_realized)
-       gdk_window_resize (widget->window, width, height);
+       gdk_window_resize (widget->window,
+                           configure_request.width,
+                           configure_request.height);
     }
   
   gtk_container_check_resize (container);
@@ -1963,6 +2457,10 @@ gtk_window_map (GtkWidget *widget)
     gdk_window_iconify (toplevel);
   else
     gdk_window_deiconify (toplevel);
+
+  /* No longer use the default settings */
+  window->need_default_size = FALSE;
+  window->need_default_position = FALSE;
   
   gdk_window_show (widget->window);
 
@@ -1974,8 +2472,7 @@ static void
 gtk_window_unmap (GtkWidget *widget)
 {
   GtkWindow *window;
-
-  g_return_if_fail (GTK_IS_WINDOW (widget));
+  GtkWindowGeometryInfo *info;    
 
   window = GTK_WINDOW (widget);
   
@@ -1984,11 +2481,22 @@ gtk_window_unmap (GtkWidget *widget)
     gdk_window_withdraw (window->frame);
   else 
     gdk_window_withdraw (widget->window);
+  
+  window->configure_request_count = 0;
+  window->configure_notify_received = FALSE;
 
-  window->use_uposition = TRUE;
-  window->resize_count = 0;
-  window->handling_resize = FALSE;
+  /* on unmap, we reset the default positioning of the window,
+   * so it's placed again, but we don't reset the default
+   * size of the window, so it's remembered.
+   */
+  window->need_default_position = TRUE;
 
+  info = gtk_window_get_geometry_info (window, FALSE);
+  if (info)
+    {
+      info->initial_pos_set = FALSE;
+      info->position_constraints_changed = FALSE;
+    }
 }
 
 static void
@@ -2130,11 +2638,30 @@ static void
 gtk_window_unrealize (GtkWidget *widget)
 {
   GtkWindow *window;
-
-  g_return_if_fail (GTK_IS_WINDOW (widget));
+  GtkWindowGeometryInfo *info;
 
   window = GTK_WINDOW (widget);
 
+  /* On unrealize, we reset the size of the window such
+   * that we will re-apply the default sizing stuff
+   * next time we show the window.
+   *
+   * Default positioning is reset on unmap, instead of unrealize.
+   */
+  window->need_default_size = TRUE;
+  info = gtk_window_get_geometry_info (window, FALSE);
+  if (info)
+    {
+      info->resize_width = -1;
+      info->resize_height = -1;
+      info->last.configure_request.x = 0;
+      info->last.configure_request.y = 0;
+      info->last.configure_request.width = -1;
+      info->last.configure_request.height = -1;
+      /* be sure we reset geom hints on re-realize */
+      info->last.flags = 0;
+    }
+  
   if (window->frame)
     {
       gdk_window_set_user_data (window->frame, NULL);
@@ -2280,42 +2807,51 @@ gtk_window_configure_event (GtkWidget         *widget,
   
   window = GTK_WINDOW (widget);
 
-  /* we got a configure event specifying the new window size and position,
-   * in principle we have to distinguish 4 cases here:
-   * 1) the size didn't change and resize_count == 0
-   *    -> the window was merely moved (sometimes not even that)
-   * 2) the size didn't change and resize_count > 0
-   *    -> we requested a new size, but didn't get it
-   * 3) the size changed and resize_count > 0
-   *    -> we asked for a new size and we got one
-   * 4) the size changed and resize_count == 0
-   *    -> we got resized from outside the toolkit, and have to
-   *    accept that size since we don't want to fight neither the
-   *    window manager nor the user
-   * in the three latter cases we have to reallocate the widget tree,
-   * which happens in gtk_window_move_resize(), so we set a flag for
-   * that function and assign the new size. if resize_count > 1,
-   * we simply do nothing and wait for more configure events.
+  /* window->configure_request_count incremented for each 
+   * configure request, and decremented to a min of 0 for
+   * each configure notify.
+   *
+   * All it means is that we know we will get at least
+   * window->configure_request_count more configure notifies.
+   * We could get more configure notifies than that; some
+   * of the configure notifies we get may be unrelated to
+   * the configure requests. But we will get at least
+   * window->configure_request_count notifies.
    */
 
-  if (window->resize_count > 0 ||
-      widget->allocation.width != event->width ||
-      widget->allocation.height != event->height)
-    {
-      if (window->resize_count > 0)
-       window->resize_count -= 1;
-
-      if (window->resize_count == 0)
-       {
-         window->handling_resize = TRUE;
-         
-         widget->allocation.width = event->width;
-         widget->allocation.height = event->height;
-         
-         gtk_widget_queue_resize (widget);
-       }
-    }
+  if (window->configure_request_count > 0)
+    window->configure_request_count -= 1;
+  
+  /* As an optimization, we avoid a resize when possible.
+   *
+   * The only times we can avoid a resize are:
+   *   - we know only the position changed, not the size
+   *   - we know we have made more requests and so will get more
+   *     notifies and can wait to resize when we get them
+   */
+  
+  if (window->configure_request_count > 0 ||
+      (widget->allocation.width == event->width &&
+       widget->allocation.height == event->height))
+    return TRUE;
 
+  /*
+   * If we do need to resize, we do that by:
+   *   - filling in widget->allocation with the new size
+   *   - setting configure_notify_received to TRUE
+   *     for use in gtk_window_move_resize()
+   *   - queueing a resize, leading to invocation of
+   *     gtk_window_move_resize() in an idle handler
+   *
+   */
+  
+  window->configure_notify_received = TRUE;
+  
+  widget->allocation.width = event->width;
+  widget->allocation.height = event->height;
+  
+  gtk_widget_queue_resize (widget);
+  
   return TRUE;
 }
 
@@ -2644,248 +3180,609 @@ gtk_window_real_set_focus (GtkWindow *window,
     gtk_widget_queue_draw (window->default_widget);
 }
 
-
-
 /*********************************
  * Functions related to resizing *
  *********************************/
 
+/* This function doesn't constrain to geometry hints */
+static void 
+gtk_window_compute_configure_request_size (GtkWindow *window,
+                                           guint     *width,
+                                           guint     *height)
+{
+  GtkRequisition requisition;
+  GtkWindowGeometryInfo *info;
+  GtkWidget *widget;
+
+  /* Preconditions:
+   *  - we've done a size request
+   */
+  
+  widget = GTK_WIDGET (window);
+
+  info = gtk_window_get_geometry_info (window, FALSE);
+  
+  if (window->need_default_size)
+    {
+      gtk_widget_get_child_requisition (widget, &requisition);
+
+      /* Default to requisition */
+      *width = requisition.width;
+      *height = requisition.height;
+
+      /* If window is empty so requests 0, default to random nonzero size */
+       if (*width == 0 && *height == 0)
+         {
+           *width = 200;
+           *height = 200;
+         }
+
+       /* Override requisition with default size */
+
+       if (info)
+         {
+           if (info->default_width > 0)
+             *width = info->default_width;
+           
+           if (info->default_height > 0)
+             *height = info->default_height;
+         }
+    }
+  else
+    {
+      /* Default to keeping current size */
+      *width = widget->allocation.width;
+      *height = widget->allocation.height;
+    }
+
+  /* Override any size with gtk_window_resize() values */
+  if (info)
+    {
+      if (info->resize_width > 0)
+        *width = info->resize_width;
+
+      if (info->resize_height > 0)
+        *height = info->resize_height;
+    }
+}
+
+static void
+gtk_window_compute_configure_request (GtkWindow    *window,
+                                      GdkRectangle *request,
+                                      GdkGeometry  *geometry,
+                                      guint        *flags)
+{
+  GdkGeometry new_geometry;
+  guint new_flags;
+  int w, h;
+  GtkWidget *widget;
+  GtkWindowPosition pos;
+  GtkWidget *parent_widget;
+  GtkWindowGeometryInfo *info;
+  int x, y;
+  
+  widget = GTK_WIDGET (window);
+  
+  gtk_widget_size_request (widget, NULL);
+  gtk_window_compute_configure_request_size (window, &w, &h);
+  
+  gtk_window_compute_hints (window, &new_geometry, &new_flags);
+  gtk_window_constrain_size (window,
+                             &new_geometry, new_flags,
+                             w, h,
+                             &w, &h);
+
+  parent_widget = (GtkWidget*) window->transient_parent;
+  
+  pos = window->position;
+  if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
+      (parent_widget == NULL ||
+       !GTK_WIDGET_MAPPED (parent_widget)))
+    pos = GTK_WIN_POS_NONE;
+
+  info = gtk_window_get_geometry_info (window, TRUE);
+
+  /* by default, don't change position requested */
+  x = info->last.configure_request.x;
+  y = info->last.configure_request.y;
+  
+  if (window->need_default_position)
+    {
+
+      /* FIXME this all interrelates with window gravity.
+       * For most of them I think we want to set GRAVITY_CENTER.
+       *
+       * Not sure how to go about that.
+       */
+      
+      switch (pos)
+        {
+          /* here we are only handling CENTER_ALWAYS
+           * as it relates to default positioning,
+           * where it's equivalent to simply CENTER
+           */
+        case GTK_WIN_POS_CENTER_ALWAYS:
+        case GTK_WIN_POS_CENTER:
+          {
+            gint screen_width = gdk_screen_width ();
+            gint screen_height = gdk_screen_height ();
+            
+            x = (screen_width - w) / 2;
+            y = (screen_height - h) / 2;
+          }
+          break;
+      
+        case GTK_WIN_POS_CENTER_ON_PARENT:
+          {
+            gint ox, oy;
+            
+            g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
+            
+            gdk_window_get_origin (parent_widget->window,
+                                   &ox, &oy);
+            
+            x = ox + (parent_widget->allocation.width - w) / 2;
+            y = oy + (parent_widget->allocation.height - h) / 2;
+          }
+          break;
+
+        case GTK_WIN_POS_MOUSE:
+          {
+            gint screen_width = gdk_screen_width ();
+            gint screen_height = gdk_screen_height ();
+            int px, py;
+            
+            gdk_window_get_pointer (NULL, &px, &py, NULL);
+            x = px - w / 2;
+            y = py - h / 2;
+            x = CLAMP (x, 0, screen_width - w);
+            y = CLAMP (y, 0, screen_height - h);
+          }
+          break;
+
+        default:
+          break;
+        }
+    } /* if (window->need_default_position) */
+
+  if (window->need_default_position &&
+      info->initial_pos_set)
+    {
+      x = info->initial_x;
+      y = info->initial_y;
+      gtk_window_constrain_position (window, w, h, &x, &y);
+    }
+  
+  request->x = x;
+  request->y = y;
+  request->width = w;
+  request->height = h;
+
+  if (geometry)
+    *geometry = new_geometry;
+  if (flags)
+    *flags = new_flags;
+}
+
+static void
+gtk_window_constrain_position (GtkWindow    *window,
+                               gint          new_width,
+                               gint          new_height,
+                               gint         *x,
+                               gint         *y)
+{
+  /* See long comments in gtk_window_move_resize()
+   * on when it's safe to call this function.
+   */
+  if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
+    {
+      gint center_x, center_y;
+      gint screen_width = gdk_screen_width ();
+      gint screen_height = gdk_screen_height ();
+      
+      center_x = (screen_width - new_width) / 2;
+      center_y = (screen_height - new_height) / 2;
+      
+      *x = center_x;
+      *y = center_y;
+    }
+}
+
 static void
 gtk_window_move_resize (GtkWindow *window)
 {
+  /* Overview:
+   *
+   * First we determine whether any information has changed that would
+   * cause us to revise our last configure request.  If we would send
+   * a different configure request from last time, then
+   * configure_request_size_changed = TRUE or
+   * configure_request_pos_changed = TRUE. configure_request_size_changed
+   * may be true due to new hints, a gtk_window_resize(), or whatever.
+   * configure_request_pos_changed may be true due to gtk_window_set_position()
+   * or gtk_window_move().
+   *
+   * If the configure request has changed, we send off a new one.  To
+   * ensure GTK invariants are maintained (resize queue does what it
+   * should), we go ahead and size_allocate the requested size in this
+   * function.
+   *
+   * If the configure request has not changed, we don't ever resend
+   * it, because it could mean fighting the user or window manager.
+   *
+   * 
+   *   To prepare the configure request, we come up with a base size/pos:
+   *      - the one from gtk_window_move()/gtk_window_resize()
+   *      - else default_width, default_height if we haven't ever
+   *        been mapped
+   *      - else the size request if we haven't ever been mapped,
+   *        as a substitute default size
+   *      - else the current size of the window, as received from
+   *        configure notifies (i.e. the current allocation)
+   *
+   *   If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
+   *   the position request to be centered.
+   */
   GtkWidget *widget;
   GtkContainer *container;
   GtkWindowGeometryInfo *info;
-  GtkWindowLastGeometryInfo saved_last_info;
   GdkGeometry new_geometry;
   guint new_flags;
-  gint x, y;
-  gint width, height;
-  gint new_width, new_height;
-  gboolean need_reposition;
-  gboolean default_size_changed = FALSE;
-  gboolean hints_changed = FALSE;
-  gboolean may_shrink = window->auto_shrink;
-
-  g_return_if_fail (GTK_WIDGET_REALIZED (window));
-
+  GdkRectangle new_request;
+  gboolean configure_request_size_changed;
+  gboolean configure_request_pos_changed;
+  gboolean hints_changed; /* do we need to send these again */
+  GtkWindowLastGeometryInfo saved_last_info;
+  
   widget = GTK_WIDGET (window);
   container = GTK_CONTAINER (widget);
   info = gtk_window_get_geometry_info (window, TRUE);
-  saved_last_info = info->last;
-
-  gtk_widget_size_request (widget, NULL);
-  gtk_window_compute_default_size (window, &new_width, &new_height);
   
-  if (info->last.width < 0 ||
-      info->last.width != new_width ||
-      info->last.height != new_height)
-    {
-      default_size_changed = TRUE;
-      may_shrink |= info->may_shrink;
-      info->last.width = new_width;
-      info->last.height = new_height;
+  configure_request_size_changed = FALSE;
+  configure_request_pos_changed = FALSE;
+  
+  gtk_window_compute_configure_request (window, &new_request,
+                                        &new_geometry, &new_flags);  
+  
+  /* This check implies the invariant that we never set info->last
+   * without setting the hints and sending off a configure request.
+   *
+   * If we change info->last without sending the request, we may
+   * miss a request.
+   */
+  if (info->last.configure_request.x != new_request.x ||
+      info->last.configure_request.y != new_request.y)
+    configure_request_pos_changed = TRUE;
+
+  /* To change, we must be different from BOTH the last request, and
+   * also our current size as received from the most recent configure
+   * notify.
+   *
+   * If different from last request, it means some sizing
+   * parameters have changed; but one possible such sizing
+   * parameter could be the current size.
+   *
+   * We never want to re-request our current size, because that could
+   * lead to some strange infinite loops if a window manager did
+   * something insane but ICCCM-compliant such as add 2 to all
+   * requested sizes. (i.e. if the WM always assigned a size that
+   * was a function of the requested size, rather than a constraint
+   * applied to requested size - so that requesting current size
+   * did not result in getting that size back)
+   *
+   * So here we detect and prevent any attempt to set size
+   * to current size.
+   *
+   * (FIXME I think some race may be possible here, but
+   *  perhaps avoided by configure_request_count?)
+   */
+  if ((info->last.configure_request.width != new_request.width ||
+       info->last.configure_request.height != new_request.height) &&
+      (widget->allocation.width != new_request.width ||
+       widget->allocation.height != new_request.height))
+    configure_request_size_changed = TRUE;
 
-      /* We need to force a reposition in this case
+  /*
+   * Position Constraints
+   * ====================
+   * 
+   * POS_CENTER_ALWAYS is conceptually a constraint rather than
+   * a default. The other POS_ values are used only when the
+   * window is shown, not after that.
+   * 
+   * However, we can't implement a position constraint as
+   * "anytime the window size changes, center the window"
+   * because this may well end up fighting the WM or user.  In
+   * fact it gets in an infinite loop with at least one WM.
+   *
+   * Basically, applications are in no way in a position to
+   * constrain the position of a window, with one exception:
+   * override redirect windows. (Really the intended purpose
+   * of CENTER_ALWAYS anyhow, I would think.)
+   *
+   * So the way we implement this "constraint" is to say that when WE
+   * cause a move or resize, i.e. we make a configure request changing
+   * window size, we recompute the CENTER_ALWAYS position to reflect
+   * the new window size, and include it in our request.  Also, if we
+   * just turned on CENTER_ALWAYS we snap to center with a new
+   * request.  Otherwise, if we are just NOTIFIED of a move or resize
+   * done by someone else e.g. the window manager, we do NOT send a
+   * new configure request.
+   *
+   * For override redirect windows, this works fine; all window
+   * sizes are from our configure requests. For managed windows,
+   * it is at least semi-sane, though who knows what the
+   * app author is thinking.
+   */
+
+  if (configure_request_pos_changed ||
+      configure_request_size_changed ||
+      info->position_constraints_changed)
+    {
+      /* We request the constrained position if:
+       *  - we were changing position, and need to clamp
+       *    the change to the constraint
+       *  - we're changing the size anyway
+       *  - set_position() was called to toggle CENTER_ALWAYS on
        */
-      if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
-       window->use_uposition = TRUE;
+
+      gtk_window_constrain_position (window,
+                                     new_request.width,
+                                     new_request.height,
+                                     &new_request.x,
+                                     &new_request.y);
+      
+      /* Update whether we need to request a move */
+      if (info->last.configure_request.x != new_request.x ||
+          info->last.configure_request.y != new_request.y)
+        configure_request_pos_changed = TRUE;
+      else
+        configure_request_pos_changed = FALSE;
     }
-  info->may_shrink = FALSE;
   
-  /* Compute new set of hints for the window
-   */
-  gtk_window_compute_hints (window, &new_geometry, &new_flags);
+  hints_changed = FALSE;
+  
   if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
                                 &new_geometry, new_flags))
     {
       hints_changed = TRUE;
-      info->last.geometry = new_geometry;
-      info->last.flags = new_flags;
     }
 
-  /* From the default size and the allocation, figure out the size
-   * the window should be.
+#if 0
+  g_print ("--- %s ---\n"
+           "last : %d,%d\t%d x %d\n"
+           "this : %d,%d\t%d x %d\n"
+           "alloc: %d,%d\t%d x %d\n"
+           "req  :      \t%d x %d\n"
+           "size_changed: %d pos_changed: %d hints_changed: %d\n"
+           "configure_notify_received: %d\n"
+           "configure_request_count: %d\n"
+           "position_constraints_changed: %d\n",
+           window->title ? window->title : "(no title)",
+           info->last.configure_request.x,
+           info->last.configure_request.y,
+           info->last.configure_request.width,
+           info->last.configure_request.height,
+           new_request.x,
+           new_request.y,
+           new_request.width,
+           new_request.height,
+           widget->allocation.x,
+           widget->allocation.y,
+           widget->allocation.width,
+           widget->allocation.height,
+           widget->requisition.width,
+           widget->requisition.height,
+           configure_request_pos_changed,
+           configure_request_size_changed,
+           hints_changed,
+           window->configure_notify_received,
+           window->configure_request_count,
+           info->position_constraints_changed);
+#endif
+  
+  saved_last_info = info->last;
+  info->last.geometry = new_geometry;
+  info->last.flags = new_flags;
+  info->last.configure_request = new_request;
+  
+  /* need to set PPosition so the WM will look at our position,
+   * but we don't want to count PPosition coming and going as a hints
+   * change for future iterations. So we saved info->last prior to
+   * this.
+   */
+  
+  /* Also, if the initial position was explicitly set, then we always
+   * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
+   * work.
    */
-  if (!default_size_changed ||
-      (!may_shrink &&
-       new_width <= widget->allocation.width &&
-       new_height <= widget->allocation.height))
-    {
-      new_width = widget->allocation.width;
-      new_height = widget->allocation.height;
-    }
-
-  /* constrain the window size to the specified geometry */
-  gtk_window_constrain_size (window,
-                            &new_geometry, new_flags,
-                            new_width, new_height,
-                            &new_width, &new_height);
 
-  /* compute new window position if a move is required
+  /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
+   * this is an initial map
    */
-  need_reposition = gtk_window_compute_reposition (window, new_width, new_height, &x, &y);
-  if (need_reposition && !(new_flags & GDK_HINT_POS))
+  
+  if ((configure_request_pos_changed ||
+       info->initial_pos_set ||
+       (window->need_default_position &&
+        window->position != GTK_WIN_POS_NONE)) &&
+      (new_flags & GDK_HINT_POS) == 0)
     {
       new_flags |= GDK_HINT_POS;
       hints_changed = TRUE;
     }
-
-
-  /* handle actual resizing:
-   * - handle reallocations due to configure events
-   * - figure whether we need to request a new window size
-   * - handle simple resizes within our widget tree
-   * - reposition window if neccessary
+  
+  /* Set hints if necessary
    */
-  width = widget->allocation.width;
-  height = widget->allocation.height;
-
-  if (window->handling_resize)
+  if (hints_changed)
+    gdk_window_set_geometry_hints (widget->window,
+                                  &new_geometry,
+                                  new_flags);
+  
+  if (window->configure_notify_received)
     { 
       GtkAllocation allocation;
-      
-      /* if we are just responding to a configure event, which
-       * might be due to a resize by the window manager, the
-       * user, or a response to a resizing request we made
-       * earlier, we go ahead, allocate the new size and we're done
+
+      /* If we have received a configure event since
+       * the last time in this function, we need to
+       * accept our new size and size_allocate child widgets.
        * (see gtk_window_configure_event() for more details).
+       *
+       * 1 or more configure notifies may have been received.
+       * Also, configure_notify_received will only be TRUE
+       * if all expected configure notifies have been received
+       * (one per configure request), as an optimization.
+       *
        */
       
-      window->handling_resize = FALSE;
-      
+      window->configure_notify_received = FALSE;
+
+      /* gtk_window_configure_event() filled in widget->allocation */
       allocation = widget->allocation;
       
       gtk_widget_size_allocate (widget, &allocation);
       gtk_widget_queue_draw (widget);
 
-      if ((default_size_changed || hints_changed) && (width != new_width || height != new_height))
-       {
-         /* We could be here for two reasons
-          *  1) We coincidentally got a resize while handling
-          *     another resize.
-          *  2) Our computation of default_size_changed was completely
-          *     screwed up, probably because one of our children
-          *     is changed requisition during size allocation).
-          *
-          * For 1), we could just go ahead and ask for the
-          * new size right now, but doing that for 2)
-          * might well be fighting the user (and can even
-          * trigger a loop). Since we really don't want to
-          * do that, we requeue a resize in hopes that
-          * by the time it gets handled, the child has seen
-          * the light and is willing to go along with the
-          * new size. (this happens for the zvt widget, since
-          * the size_allocate() above will have stored the
-          * requisition corresponding to the new size in the
-          * zvt widget)
-          *
-          * This doesn't buy us anything for 1), but it shouldn't
-          * hurt us too badly, since it is what would have
-          * happened if we had gotten the configure event before
-          * the new size had been set.
-          */
-         
-         if (need_reposition)
-           {
-             if (window->frame)
-               gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
-             else
-               gdk_window_move (GTK_WIDGET (window)->window, x, y);
-           }
+      /* If the configure request changed, it means that
+       * we either:
+       *   1) coincidentally changed hints or widget properties
+       *      impacting the configure request before getting
+       *      a configure notify
+       *  or
+       *   2) some broken widget is changing its size request
+       *      during size allocation, resulting in
+       *      a false appearance of changed configure request.
+       *
+       * For 1), we could just go ahead and ask for the
+       * new size right now, but doing that for 2)
+       * might well be fighting the user (and can even
+       * trigger a loop). Since we really don't want to
+       * do that, we requeue a resize in hopes that
+       * by the time it gets handled, the child has seen
+       * the light and is willing to go along with the
+       * new size. (this happens for the zvt widget, since
+       * the size_allocate() above will have stored the
+       * requisition corresponding to the new size in the
+       * zvt widget)
+       *
+       * This doesn't buy us anything for 1), but it shouldn't
+       * hurt us too badly, since it is what would have
+       * happened if we had gotten the configure event before
+       * the new size had been set.
+       * 
+       */
 
-         /* we have to preserve the values and flags that are used
-          * for computation of default_size_changed and hints_changed
-          */
+      if (configure_request_size_changed ||
+          configure_request_pos_changed)
+        {
+          /* Don't change the recorded last info after all, because we
+           * haven't actually updated to the new info yet - we decided
+           * to postpone our configure request until later.
+           */
+          
          info->last = saved_last_info;
-         
+          
          gtk_widget_queue_resize (widget);
-
-         return;
        }
     }
-
-  /* Now set hints if necessary
-   */
-  if (hints_changed)
-    gdk_window_set_geometry_hints (widget->window,
-                                  &new_geometry,
-                                  new_flags);
-
-  if ((default_size_changed || hints_changed) &&
-      (width != new_width || height != new_height))
+  else if (configure_request_pos_changed ||
+           configure_request_size_changed ||
+           hints_changed)
     {
-      /* given that (width != new_width || height != new_height), we are in one
-       * of the following situations:
+      /* We are in one of the following situations with
+       * respect to the window size:
        * 
-       * default_size_changed
+       * A. configure_request_size_changed
        *   our requisition has changed and we need a different window size,
        *   so we request it from the window manager.
        *
-       * !default_size_changed
+       * B. !configure_request_size_changed
        *   the window manager wouldn't assign us the size we requested, in this
        *   case we don't try to request a new size with every resize.
        *
-       * !default_size_changed && hints_changed
+       * C. !configure_request_size_changed && hints_changed
        *   the window manager rejects our size, but we have just changed the
        *   window manager hints, so there's a certain chance our request will
        *   be honoured this time, so we try again.
        */
+
+      /* Compress case C into case A */
+      if (hints_changed)
+        configure_request_size_changed = TRUE;
+
+      g_assert (configure_request_size_changed ||
+                configure_request_pos_changed);
       
-      /* request a new window size */
-      if (need_reposition)
+      /* Now send the configure request */
+
+      if (configure_request_pos_changed)
        {
          if (window->frame)
            {
              gdk_window_move_resize (window->frame,
-                                     x - window->frame_left, y - window->frame_top,
-                                     new_width + window->frame_left + window->frame_right,
-                                     new_height + window->frame_top + window->frame_bottom);
-             gdk_window_resize (GTK_WIDGET (window)->window, new_width, new_height);
+                                     new_request.x - window->frame_left,
+                                      new_request.y - window->frame_top,
+                                     new_request.width + window->frame_left + window->frame_right,
+                                     new_request.height + window->frame_top + window->frame_bottom);
+             gdk_window_resize (GTK_WIDGET (window)->window,
+                                 new_request.width, new_request.height);
            }
          else
-           gdk_window_move_resize (GTK_WIDGET (window)->window, x, y, new_width, new_height);
+           gdk_window_move_resize (widget->window,
+                                    new_request.x, new_request.y,
+                                    new_request.width, new_request.height);
        }
       else
        {
+          /* only size changed */
+          
          if (window->frame)
            gdk_window_resize (window->frame,
-                              new_width + window->frame_left + window->frame_right,
-                              new_height + window->frame_top + window->frame_bottom);
-         gdk_window_resize (GTK_WIDGET (window)->window, new_width, new_height);
+                              new_request.width + window->frame_left + window->frame_right,
+                              new_request.height + window->frame_top + window->frame_bottom);
+
+         gdk_window_resize (widget->window,
+                             new_request.width, new_request.height);
        }
-      window->resize_count += 1;
       
-      /* we are now awaiting the new configure event in response to our
+      /* Increment the number of have-not-yet-received-notify requests */
+      window->configure_request_count += 1;
+
+      /* We have now sent a request since the last position constraint
+       * change
+       */
+      info->position_constraints_changed = FALSE;
+      
+      /* we are now awaiting the new configure notify event in response to our
        * resizing request. the configure event will cause a new resize
-       * with ->handling_resize=TRUE.
+       * with ->configure_notify_received=TRUE.
        * until then, we want to
        * - discard expose events
        * - coalesce resizes for our children
        * - defer any window resizes until the configure event arrived
-       * to achive this, we queue a resize for the window, but remove its
+       * to achieve this, we queue a resize for the window, but remove its
        * resizing handler, so resizing will not be handled from the next
        * idle handler but when the configure event arrives.
        *
        * FIXME: we should also dequeue the pending redraws here, since
-       * we handle those ourselves in ->handling_resize==TRUE.
+       * we handle those ourselves in ->configure_notify_received==TRUE.
+       *
+       * FIXME: not sure the above FIXME is correct, because we only
+       * queue draw in size allocate if the size actually changes,
+       * so if the update area for the window contains stuff
+       * unrelated to sizing (should be rare actually) then we
+       * might lose that info.
        */
-      gtk_widget_queue_resize (GTK_WIDGET (container));
+      gtk_widget_queue_resize (widget);
       if (container->resize_mode == GTK_RESIZE_QUEUE)
        _gtk_container_dequeue_resize_handler (container);
     }
   else
     {
-      if (need_reposition)
-       {
-         if (window->frame)
-           gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
-         else
-           gdk_window_move (widget->window, x, y);
-       }
-
+      /* Not requesting anything new from WM, just had a queue resize
+       * for some reason, so handle the resize queue
+       */
       if (container->resize_widgets)
-       gtk_container_resize_children (GTK_CONTAINER (window));
+        gtk_container_resize_children (container);
     }
 }
 
@@ -2932,40 +3829,6 @@ gtk_window_compare_hints (GdkGeometry *geometry_a,
   return TRUE;
 }
 
-/* Compute the default_size for a window. The result will
- * be stored in *width and *height. The default size is
- * the size the window should have when initially mapped.
- * This routine does not attempt to constrain the size
- * to obey the geometry hints - that must be done elsewhere.
- */
-static void 
-gtk_window_compute_default_size (GtkWindow       *window,
-                                guint           *width,
-                                guint           *height)
-{
-  GtkRequisition requisition;
-  GtkWindowGeometryInfo *info;
-  
-  gtk_widget_get_child_requisition (GTK_WIDGET (window), &requisition);
-  *width = requisition.width;
-  *height = requisition.height;
-
-  info = gtk_window_get_geometry_info (window, FALSE);
-  
-  if (*width == 0 && *height == 0)
-    {
-      /* empty window */
-      *width = 200;
-      *height = 200;
-    }
-  
-  if (info)
-    {
-      *width = info->width > 0 ? info->width : *width;
-      *height = info->height > 0 ? info->height : *height;
-    }
-}
-
 void
 _gtk_window_constrain_size (GtkWindow   *window,
                            gint         width,
@@ -3017,8 +3880,6 @@ gtk_window_compute_hints (GtkWindow   *window,
                          guint       *new_flags)
 {
   GtkWidget *widget;
-  GtkWidgetAuxInfo *aux_info;
-  gint ux, uy;
   gint extra_width = 0;
   gint extra_height = 0;
   GtkWindowGeometryInfo *geometry_info;
@@ -3031,27 +3892,26 @@ gtk_window_compute_hints (GtkWindow   *window,
   gtk_widget_get_child_requisition (widget, &requisition);
   geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
 
-  g_return_if_fail (geometry_info != NULL);
-  
-  *new_flags = geometry_info->mask;
-  *new_geometry = geometry_info->geometry;
-  
-  if (geometry_info->widget)
+  if (geometry_info)
     {
-      extra_width = widget->requisition.width - geometry_info->widget->requisition.width;
-      extra_height = widget->requisition.height - geometry_info->widget->requisition.height;
+      *new_flags = geometry_info->mask;
+      *new_geometry = geometry_info->geometry;
+    }
+  else
+    {
+      *new_flags = 0;
     }
   
-  ux = 0;
-  uy = 0;
-  
-  aux_info = _gtk_widget_get_aux_info (widget, FALSE);
-  if (aux_info && aux_info->x_set && aux_info->y_set)
+  if (geometry_info && geometry_info->widget)
     {
-      ux = aux_info->x;
-      uy = aux_info->y;
-      *new_flags |= GDK_HINT_POS;
+      extra_width = widget->requisition.width - geometry_info->widget->requisition.width;
+      extra_height = widget->requisition.height - geometry_info->widget->requisition.height;
     }
+
+  /* We don't want to set GDK_HINT_POS in here, we just set it
+   * in gtk_window_move_resize() when we want the position
+   * honored.
+   */
   
   if (*new_flags & GDK_HINT_BASE_SIZE)
     {
@@ -3073,10 +3933,10 @@ gtk_window_compute_hints (GtkWindow   *window,
       if (new_geometry->min_width < 0)
        new_geometry->min_width = requisition.width;
       else
-       new_geometry->min_width += extra_width;
+        new_geometry->min_width += extra_width;
 
       if (new_geometry->min_height < 0)
-       new_geometry->min_width = requisition.height;
+       new_geometry->min_height = requisition.height;
       else
        new_geometry->min_height += extra_height;
     }
@@ -3112,106 +3972,6 @@ gtk_window_compute_hints (GtkWindow   *window,
   new_geometry->win_gravity = window->gravity;
 }
 
-/* Compute a new position for the window based on a new
- * size. *x and *y will be set to the new coordinates. Returns
- * TRUE if the window needs to be moved (and thus x and y got
- * assigned)
- */
-static gint
-gtk_window_compute_reposition (GtkWindow *window,
-                              gint       new_width,
-                              gint       new_height,
-                              gint      *x,
-                              gint      *y)
-{
-  GtkWidget *widget = GTK_WIDGET (window);
-  GtkWindowPosition pos;
-  GtkWidget *parent_widget;
-  gboolean needs_move = FALSE;
-
-  parent_widget = (GtkWidget*) window->transient_parent;
-  
-  pos = window->position;
-  if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
-      (parent_widget == NULL ||
-       !GTK_WIDGET_MAPPED (parent_widget)))
-    pos = GTK_WIN_POS_NONE;
-  
-  switch (pos)
-  {
-    case GTK_WIN_POS_CENTER:
-    case GTK_WIN_POS_CENTER_ALWAYS:
-      if (window->use_uposition)
-       {
-         gint screen_width = gdk_screen_width ();
-         gint screen_height = gdk_screen_height ();
-         
-         *x = (screen_width - new_width) / 2;
-         *y = (screen_height - new_height) / 2;
-         needs_move = TRUE;
-       }
-      break;
-
-    case GTK_WIN_POS_CENTER_ON_PARENT:
-      if (window->use_uposition)
-        {
-          gint ox, oy;
-         gdk_window_get_origin (parent_widget->window,
-                                  &ox, &oy);
-                                 
-          *x = ox + (parent_widget->allocation.width - new_width) / 2;
-          *y = oy + (parent_widget->allocation.height - new_height) / 2;
-         needs_move = TRUE;
-       }
-      break;
-
-    case GTK_WIN_POS_MOUSE:
-      if (window->use_uposition)
-       {
-         gint screen_width = gdk_screen_width ();
-         gint screen_height = gdk_screen_height ();
-         
-         gdk_window_get_pointer (NULL, x, y, NULL);
-         *x -= new_width / 2;
-         *y -= new_height / 2;
-         *x = CLAMP (*x, 0, screen_width - new_width);
-         *y = CLAMP (*y, 0, screen_height - new_height);
-         needs_move = TRUE;
-       }
-      break;
-    default:
-      if (window->use_uposition)
-       {
-         GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
-
-         if (aux_info && aux_info->x_set && aux_info->y_set)
-           {
-             *x = aux_info->x;
-             *y = aux_info->y;
-             needs_move = TRUE;
-           }
-       }
-      break;
-    }
-
-  if (needs_move)
-    {
-      GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, TRUE);
-
-      /* we handle necessary window positioning by hand here,
-       * so we can coalesce the window movement with possible
-       * resizes to get only one configure event.
-       */
-      aux_info->x_set = TRUE;
-      aux_info->y_set = TRUE;
-      aux_info->x = *x;
-      aux_info->y = *y;
-      window->use_uposition = FALSE;
-    }
-
-  return needs_move;
-}
-
 /***********************
  * Redrawing functions *
  ***********************/
@@ -3639,23 +4399,12 @@ gtk_window_get_resizable (GtkWindow *window)
  * @window: a #GtkWindow
  * @gravity: window gravity
  *
- * Window gravity defines the "reference point" to be used when
- * positioning or resizing a window. Calls to
- * gtk_widget_set_uposition() will position a different point on the
- * window depending on the window gravity. When the window changes size
- * the reference point determined by the window's gravity will stay in
- * a fixed location.
+ * Window gravity defines the meaning of coordinates passed to
+ * gtk_window_move(). See gtk_window_move() and #GdkGravity for
+ * more details.
  *
- * See #GdkGravity for full details. To briefly summarize,
- * #GDK_GRAVITY_NORTH_WEST means that the reference point is the
- * northwest (top left) corner of the window
- * frame. #GDK_GRAVITY_SOUTH_EAST would be the bottom right corner of
- * the frame, and so on. If you want to position the window contents,
- * rather than the window manager's frame, #GDK_GRAVITY_STATIC moves
- * the reference point to the northwest corner of the #GtkWindow
- * itself.
- *
- * The default window gravity is #GDK_GRAVITY_NORTH_WEST.
+ * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
+ * typically "do what you mean."
  *
  **/
 void
@@ -3945,3 +4694,286 @@ _gtk_window_get_group (GtkWindow *window)
       return default_group;
     }
 }
+
+
+/*
+  Derived from XParseGeometry() in XFree86  
+
+  Copyright 1985, 1986, 1987,1998  The Open Group
+
+  All Rights Reserved.
+
+  The above copyright notice and this permission notice shall be included
+  in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+  IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+  OTHER DEALINGS IN THE SOFTWARE.
+
+  Except as contained in this notice, the name of The Open Group shall
+  not be used in advertising or otherwise to promote the sale, use or
+  other dealings in this Software without prior written authorization
+  from The Open Group.
+*/
+
+
+/*
+ *    XParseGeometry parses strings of the form
+ *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
+ *   width, height, xoffset, and yoffset are unsigned integers.
+ *   Example:  "=80x24+300-49"
+ *   The equal sign is optional.
+ *   It returns a bitmask that indicates which of the four values
+ *   were actually found in the string.  For each value found,
+ *   the corresponding argument is updated;  for each value
+ *   not found, the corresponding argument is left unchanged. 
+ */
+
+/* The following code is from Xlib, and is minimally modified, so we
+ * can track any upstream changes if required.  Don't change this
+ * code. Or if you do, put in a huge comment marking which thing
+ * changed.
+ */
+
+static int
+read_int (gchar   *string,
+          gchar  **next)
+{
+  int result = 0;
+  int sign = 1;
+  
+  if (*string == '+')
+    string++;
+  else if (*string == '-')
+    {
+      string++;
+      sign = -1;
+    }
+
+  for (; (*string >= '0') && (*string <= '9'); string++)
+    {
+      result = (result * 10) + (*string - '0');
+    }
+
+  *next = string;
+
+  if (sign >= 0)
+    return (result);
+  else
+    return (-result);
+}
+
+/* 
+ * Bitmask returned by XParseGeometry().  Each bit tells if the corresponding
+ * value (x, y, width, height) was found in the parsed string.
+ */
+#define NoValue         0x0000
+#define XValue          0x0001
+#define YValue          0x0002
+#define WidthValue      0x0004
+#define HeightValue     0x0008
+#define AllValues       0x000F
+#define XNegative       0x0010
+#define YNegative       0x0020
+
+/* Try not to reformat/modify, so we can compare/sync with X sources */
+static int
+gtk_XParseGeometry (const char   *string,
+                    int          *x,
+                    int          *y,
+                    unsigned int *width,   
+                    unsigned int *height)  
+{
+  int mask = NoValue;
+  char *strind;
+  unsigned int tempWidth, tempHeight;
+  int tempX, tempY;
+  char *nextCharacter;
+
+  if ( (string == NULL) || (*string == '\0')) return(mask);
+  if (*string == '=')
+    string++;  /* ignore possible '=' at beg of geometry spec */
+
+  strind = (char *)string;
+  if (*strind != '+' && *strind != '-' && *strind != 'x') {
+    tempWidth = read_int(strind, &nextCharacter);
+    if (strind == nextCharacter) 
+      return (0);
+    strind = nextCharacter;
+    mask |= WidthValue;
+  }
+
+  if (*strind == 'x' || *strind == 'X') {      
+    strind++;
+    tempHeight = read_int(strind, &nextCharacter);
+    if (strind == nextCharacter)
+      return (0);
+    strind = nextCharacter;
+    mask |= HeightValue;
+  }
+
+  if ((*strind == '+') || (*strind == '-')) {
+    if (*strind == '-') {
+      strind++;
+      tempX = -read_int(strind, &nextCharacter);
+      if (strind == nextCharacter)
+        return (0);
+      strind = nextCharacter;
+      mask |= XNegative;
+
+    }
+    else
+      {        strind++;
+      tempX = read_int(strind, &nextCharacter);
+      if (strind == nextCharacter)
+        return(0);
+      strind = nextCharacter;
+      }
+    mask |= XValue;
+    if ((*strind == '+') || (*strind == '-')) {
+      if (*strind == '-') {
+        strind++;
+        tempY = -read_int(strind, &nextCharacter);
+        if (strind == nextCharacter)
+          return(0);
+        strind = nextCharacter;
+        mask |= YNegative;
+
+      }
+      else
+        {
+          strind++;
+          tempY = read_int(strind, &nextCharacter);
+          if (strind == nextCharacter)
+            return(0);
+          strind = nextCharacter;
+        }
+      mask |= YValue;
+    }
+  }
+       
+  /* If strind isn't at the end of the string the it's an invalid
+               geometry specification. */
+
+  if (*strind != '\0') return (0);
+
+  if (mask & XValue)
+    *x = tempX;
+  if (mask & YValue)
+    *y = tempY;
+  if (mask & WidthValue)
+    *width = tempWidth;
+  if (mask & HeightValue)
+    *height = tempHeight;
+  return (mask);
+}
+
+/**
+ * gtk_window_parse_geometry:
+ * @window: a #GtkWindow
+ * @geometry: geometry string
+ * 
+ * Parses a standard X Window System geometry string - see the
+ * manual page for X (type 'man X') for details on this.
+ * gtk_window_parse_geometry() does work on all GTK+ ports
+ * including Win32 but is primarily intended for an X environment.
+ *
+ * If either a size or a position can be extracted from the
+ * geometry string, gtk_window_parse_geometry() returns %TRUE
+ * and calls gtk_window_set_default_size() and/or gtk_window_move()
+ * to resize/move the window.
+ *
+ * If gtk_window_parse_geometry() returns %TRUE, it will also
+ * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
+ * indicating to the window manager that the size/position of
+ * the window was user-specified. This causes most window
+ * managers to honor the geometry.
+ * 
+ * Return value: %TRUE if string was parsed successfully
+ **/
+gboolean
+gtk_window_parse_geometry (GtkWindow   *window,
+                           const gchar *geometry)
+{
+  gint result, x, y;
+  guint w, h;
+  GdkGravity grav;
+  gboolean size_set, pos_set;
+  
+  g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+  g_return_val_if_fail (geometry != NULL, FALSE);
+  
+  result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
+
+  if ((result & WidthValue) == 0 ||
+      w < 0)
+    w = -1;
+  if ((result & HeightValue) == 0 ||
+      h < 0)
+    h = -1;
+
+  size_set = FALSE;
+  if ((result & WidthValue) || (result & HeightValue))
+    {
+      gtk_window_set_default_size (window, w, h);
+      size_set = TRUE;
+    }
+
+  gtk_window_get_size (window, &w, &h);
+  
+  grav = GDK_GRAVITY_NORTH_WEST;
+
+  if ((result & XNegative) && (result & YNegative))
+    grav = GDK_GRAVITY_SOUTH_EAST;
+  else if (result & XNegative)
+    grav = GDK_GRAVITY_NORTH_EAST;
+  else if (result & YNegative)
+    grav = GDK_GRAVITY_SOUTH_WEST;
+
+  if ((result & XValue) == 0)
+    x = 0;
+
+  if ((result & YValue) == 0)
+    y = 0;
+  
+  if (grav == GDK_GRAVITY_SOUTH_WEST ||
+      grav == GDK_GRAVITY_SOUTH_EAST)
+    y = gdk_screen_height () - h;
+
+  if (grav == GDK_GRAVITY_SOUTH_EAST ||
+      grav == GDK_GRAVITY_NORTH_EAST)
+    x = gdk_screen_width () - w;
+
+  if (y < 0)
+    y = 0;
+
+  if (x < 0)
+    x = 0;
+
+  pos_set = FALSE;
+  if ((result & XValue) || (result & YValue))
+    {
+      gtk_window_set_gravity (window, grav);
+      gtk_window_move (window, x, y);
+      pos_set = TRUE;
+    }
+
+  if (size_set || pos_set)
+    {
+      /* Set USSize, USPosition hints */
+      GtkWindowGeometryInfo *info;
+
+      info = gtk_window_get_geometry_info (window, TRUE);
+
+      if (pos_set)
+        info->mask |= GDK_HINT_USER_POS;
+      if (size_set)
+        info->mask |= GDK_HINT_USER_SIZE;
+    }
+  
+  return result != 0;
+}
index 282909cff783a17020bed43cf77153239cfd4bbf..7753d02dd61822990a0cd6779e79140ac1c3856e 100644 (file)
@@ -69,24 +69,23 @@ struct _GtkWindow
   GdkWindow *frame;
   GtkWindowGroup *group;
 
-  guint16 resize_count;
-
-  GtkWindowType type : 4;
-  guint has_user_ref_count : 1;
-  guint has_focus : 1;
+  guint16 configure_request_count;
   guint allow_shrink : 1;
   guint allow_grow : 1;
-  guint auto_shrink : 1;
-  guint handling_resize : 1;
-  guint position : 2;
-
-  /* The following flag is initially TRUE when a window is mapped.
-   * and will be set to FALSE after it is first positioned.
-   * It is also temporarily reset when the window's size changes.
-   * 
-   * When TRUE, we move the window to the position the app set.
+  guint configure_notify_received : 1;
+  /* The following flags are initially TRUE (before a window is mapped).
+   * They cause us to compute a configure request that involves
+   * default-only parameters. Once mapped, we set them to FALSE.
+   * Then we set them to TRUE again on unmap (for position)
+   * and on unrealize (for size).
    */
-  guint use_uposition : 1;
+  guint need_default_position : 1;
+  guint need_default_size : 1;
+  guint position : 3;
+  GtkWindowType type : 4;
+  guint has_user_ref_count : 1;
+  guint has_focus : 1;
+
   guint modal : 1;
   guint destroy_with_parent : 1;
   
@@ -252,16 +251,33 @@ void       gtk_window_set_policy               (GtkWindow           *window,
                                                gint                 allow_grow,
                                                gint                 auto_shrink);
 #endif
-/* The following differs from gtk_widget_set_usize, in that
- * gtk_widget_set_usize() overrides the requisition, so sets a minimum
- * size, while this only sets the size requested from the WM.
+
+/* Set initial default size of the window (does not constrain user
+ * resize operations)
  */
-void       gtk_window_set_default_size         (GtkWindow           *window,
-                                               gint                 width,
-                                               gint                 height);
-void       gtk_window_get_default_size         (GtkWindow           *window,
-                                               gint                *width,
-                                               gint                *height);
+void     gtk_window_set_default_size (GtkWindow   *window,
+                                      gint         width,
+                                      gint         height);
+void     gtk_window_get_default_size (GtkWindow   *window,
+                                      gint        *width,
+                                      gint        *height);
+void     gtk_window_resize           (GtkWindow   *window,
+                                      gint         width,
+                                      gint         height);
+void     gtk_window_get_size         (GtkWindow   *window,
+                                      gint        *width,
+                                      gint        *height);
+void     gtk_window_move             (GtkWindow   *window,
+                                      gint         x,
+                                      gint         y);
+void     gtk_window_get_position     (GtkWindow   *window,
+                                      gint        *x,
+                                      gint        *y);
+gboolean gtk_window_parse_geometry   (GtkWindow   *window,
+                                      const gchar *geometry);
+
+/* Ignore this unless you are writing a GUI builder */
+void     gtk_window_reshow_with_initial_size (GtkWindow *window);
 
 /* Window groups
  */
index 2cbf63dfaaff84ef093aa22f7145dd5ae13247db..37f470300809028a5cf1e245bc421b0b143f9033 100644 (file)
@@ -8109,16 +8109,10 @@ configure_event_callback (GtkWidget *widget,
   gchar *msg;
   gint x, y;
   
-#if 0
-  /* FIXME */
-  gtk_window_get_location (GTK_WINDOW (widget), &x, &y);
-#else  
-  x = 0;
-  y = 0;
-#endif
+  gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
   
   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
-                         "location: %d, %d",
+                         "position: %d, %d",
                          event->x, event->y, event->width, event->height,
                          x, y);
   
@@ -8152,9 +8146,17 @@ set_size_callback (GtkWidget *widget,
   
   get_ints (data, &w, &h);
 
-  gtk_window_set_default_size (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
+  gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
 }
-     
+
+static void
+unset_default_size_callback (GtkWidget *widget,
+                             gpointer   data)
+{
+  gtk_window_set_default_size (g_object_get_data (data, "target"),
+                               -1, -1);
+}
+
 static void
 set_default_size_callback (GtkWidget *widget,
                            gpointer   data)
@@ -8167,6 +8169,14 @@ set_default_size_callback (GtkWidget *widget,
                                w, h);
 }
 
+static void
+unset_usize_callback (GtkWidget *widget,
+                      gpointer   data)
+{
+  gtk_widget_set_size_request (g_object_get_data (data, "target"),
+                               -1, -1);
+}
+
 static void
 set_usize_callback (GtkWidget *widget,
                     gpointer   data)
@@ -8175,8 +8185,8 @@ set_usize_callback (GtkWidget *widget,
   
   get_ints (data, &w, &h);
 
-  gtk_widget_set_usize (g_object_get_data (data, "target"),
-                        w, h);
+  gtk_widget_set_size_request (g_object_get_data (data, "target"),
+                               w, h);
 }
 
 static void
@@ -8187,7 +8197,21 @@ set_location_callback (GtkWidget *widget,
   
   get_ints (data, &x, &y);
 
-  gtk_widget_set_uposition (g_object_get_data (data, "target"), x, y);
+  gtk_window_move (g_object_get_data (data, "target"), x, y);
+}
+
+static void
+move_to_position_callback (GtkWidget *widget,
+                           gpointer   data)
+{
+  gint x, y;
+  GtkWindow *window;
+
+  window = g_object_get_data (data, "target");
+  
+  gtk_window_get_position (window, &x, &y);
+
+  gtk_window_move (window, x, y);
 }
 
 static void
@@ -8201,12 +8225,9 @@ set_geometry_callback (GtkWidget *entry,
   
   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
 
-#if 0
-  /* FIXME */
   if (!gtk_window_parse_geometry (target, text))
     g_print ("Bad geometry string '%s'\n", text);
-#endif
-  
+
   g_free (text);
 }
 
@@ -8242,12 +8263,232 @@ auto_shrink_callback (GtkWidget *widget,
 
 static void
 gravity_selected (GtkWidget *widget,
-                  gpointer data)
+                  gpointer   data)
 {
   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
                           gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GDK_GRAVITY_NORTH_WEST);
 }
 
+static void
+pos_selected (GtkWidget *widget,
+              gpointer   data)
+{
+  gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
+                           gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GTK_WIN_POS_NONE);
+}
+
+static void
+move_gravity_window_to_current_position (GtkWidget *widget,
+                                         gpointer   data)
+{
+  gint x, y;
+  GtkWindow *window;
+
+  window = GTK_WINDOW (data);    
+  
+  gtk_window_get_position (window, &x, &y);
+
+  gtk_window_move (window, x, y);
+}
+
+static void
+get_screen_corner (GtkWindow *window,
+                   gint      *x,
+                   gint      *y)
+{
+  int w, h;
+  
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+
+  switch (gtk_window_get_gravity (window))
+    {
+    case GDK_GRAVITY_SOUTH_EAST:
+      *x = gdk_screen_width () - w;
+      *y = gdk_screen_height () - h;
+      break;
+
+    case GDK_GRAVITY_NORTH_EAST:
+      *x = gdk_screen_width () - w;
+      *y = 0;
+      break;
+
+    case GDK_GRAVITY_SOUTH_WEST:
+      *x = 0;
+      *y = gdk_screen_height () - h;
+      break;
+
+    case GDK_GRAVITY_NORTH_WEST:
+      *x = 0;
+      *y = 0;
+      break;
+      
+    case GDK_GRAVITY_SOUTH:
+      *x = (gdk_screen_width () - w) / 2;
+      *y = gdk_screen_height () - h;
+      break;
+
+    case GDK_GRAVITY_NORTH:
+      *x = (gdk_screen_width () - w) / 2;
+      *y = 0;
+      break;
+
+    case GDK_GRAVITY_WEST:
+      *x = 0;
+      *y = (gdk_screen_height () - h) / 2;
+      break;
+
+    case GDK_GRAVITY_EAST:
+      *x = gdk_screen_width () - w;
+      *y = (gdk_screen_height () - h) / 2;
+      break;
+
+    case GDK_GRAVITY_CENTER:
+      *x = (gdk_screen_width () - w) / 2;
+      *y = (gdk_screen_height () - h) / 2;
+      break;
+
+    case GDK_GRAVITY_STATIC:
+      /* pick some random numbers */
+      *x = 350;
+      *y = 350;
+      break;
+
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+}
+
+static void
+move_gravity_window_to_starting_position (GtkWidget *widget,
+                                          gpointer   data)
+{
+  gint x, y;
+  GtkWindow *window;
+
+  window = GTK_WINDOW (data);    
+  
+  get_screen_corner (window,
+                     &x, &y);
+  
+  gtk_window_move (window, x, y);
+}
+
+static GtkWidget*
+make_gravity_window (GtkWidget   *destroy_with,
+                     GdkGravity   gravity,
+                     const gchar *title)
+{
+  GtkWidget *window;
+  GtkWidget *button;
+  GtkWidget *vbox;
+  int x, y;
+  
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  vbox = gtk_vbox_new (FALSE, 0);
+  gtk_widget_show (vbox);
+  
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+  gtk_window_set_title (GTK_WINDOW (window), title);
+  gtk_window_set_gravity (GTK_WINDOW (window), gravity);
+
+  gtk_signal_connect_object (GTK_OBJECT (destroy_with),
+                             "destroy",
+                             GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                             GTK_OBJECT (window));
+
+  
+  button = gtk_button_new_with_mnemonic ("_Move to current position");
+
+  g_signal_connect (G_OBJECT (button), "clicked",
+                    G_CALLBACK (move_gravity_window_to_current_position),
+                    window);
+
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+  gtk_widget_show (button);
+
+  button = gtk_button_new_with_mnemonic ("Move to _starting position");
+
+  g_signal_connect (G_OBJECT (button), "clicked",
+                    G_CALLBACK (move_gravity_window_to_starting_position),
+                    window);
+
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+  gtk_widget_show (button);
+  
+  /* Pretend this is the result of --geometry.
+   * DO NOT COPY THIS CODE unless you are setting --geometry results,
+   * and in that case you probably should just use gtk_window_parse_geometry().
+   * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
+   * you are parsing --geometry or equivalent.
+   */
+  gtk_window_set_geometry_hints (GTK_WINDOW (window),
+                                 NULL, NULL,
+                                 GDK_HINT_USER_POS);
+
+  gtk_window_set_default_size (GTK_WINDOW (window),
+                               200, 200);
+
+  get_screen_corner (GTK_WINDOW (window), &x, &y);
+  
+  gtk_window_move (GTK_WINDOW (window),
+                   x, y);
+  
+  return window;
+}
+
+static void
+do_gravity_test (GtkWidget *widget,
+                 gpointer   data)
+{
+  GtkWidget *destroy_with = data;
+  GtkWidget *window;
+  
+  /* We put a window at each gravity point on the screen. */
+  window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
+                                "NorthWest");
+  gtk_widget_show (window);
+  
+  window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
+                                "SouthEast");
+  gtk_widget_show (window);
+
+  window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
+                                "NorthEast");
+  gtk_widget_show (window);
+
+  window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
+                                "SouthWest");
+  gtk_widget_show (window);
+
+  window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
+                                "South");
+  gtk_widget_show (window);
+
+  window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
+                                "North");
+  gtk_widget_show (window);
+
+  
+  window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
+                                "West");
+  gtk_widget_show (window);
+
+    
+  window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
+                                "East");
+  gtk_widget_show (window);
+
+  window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
+                                "Center");
+  gtk_widget_show (window);
+
+  window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
+                                "Static");
+  gtk_widget_show (window);
+}
+
 static GtkWidget*
 window_controls (GtkWidget *window)
 {
@@ -8287,7 +8528,7 @@ window_controls (GtkWidget *window)
                       GTK_SIGNAL_FUNC (configure_event_callback),
                       label);
 
-  adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -3.0, 800.0, 1.0,
+  adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
                                               5.0, 0.0);
   spin = gtk_spin_button_new (adj, 0, 0);
 
@@ -8295,7 +8536,7 @@ window_controls (GtkWidget *window)
 
   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
 
-  adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -3.0, 800.0, 1.0,
+  adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
                                               5.0, 0.0);
   spin = gtk_spin_button_new (adj, 0, 0);
 
@@ -8309,15 +8550,29 @@ window_controls (GtkWidget *window)
   gtk_signal_connect (GTK_OBJECT (entry), "changed",
                       GTK_SIGNAL_FUNC (set_geometry_callback),
                       control_window);
+
+  button = gtk_button_new_with_label ("Show gravity test windows");
+  gtk_signal_connect_object (GTK_OBJECT (button),
+                             "clicked",
+                             GTK_SIGNAL_FUNC (do_gravity_test),
+                             control_window);
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_button_new_with_label ("Reshow with initial size");
+  gtk_signal_connect_object (GTK_OBJECT (button),
+                             "clicked",
+                             GTK_SIGNAL_FUNC (gtk_window_reshow_with_initial_size),
+                             GTK_OBJECT (window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
   
   button = gtk_button_new_with_label ("Queue resize");
   gtk_signal_connect_object (GTK_OBJECT (button),
                              "clicked",
                              GTK_SIGNAL_FUNC (gtk_widget_queue_resize),
-                             GTK_OBJECT (control_window));
+                             GTK_OBJECT (window));
   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
   
-  button = gtk_button_new_with_label ("Set size");
+  button = gtk_button_new_with_label ("Resize");
   gtk_signal_connect (GTK_OBJECT (button),
                       "clicked",
                       GTK_SIGNAL_FUNC (set_size_callback),
@@ -8331,20 +8586,41 @@ window_controls (GtkWidget *window)
                       GTK_OBJECT (control_window));
   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
 
-  button = gtk_button_new_with_label ("Set usize");
+  button = gtk_button_new_with_label ("Unset default size");
+  gtk_signal_connect (GTK_OBJECT (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (unset_default_size_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  
+  button = gtk_button_new_with_label ("Set size request");
   gtk_signal_connect (GTK_OBJECT (button),
                       "clicked",
                       GTK_SIGNAL_FUNC (set_usize_callback),
                       GTK_OBJECT (control_window));
   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
 
-  button = gtk_button_new_with_label ("Set location");
+  button = gtk_button_new_with_label ("Unset size request");
+  gtk_signal_connect (GTK_OBJECT (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (unset_usize_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  
+  button = gtk_button_new_with_label ("Move");
   gtk_signal_connect (GTK_OBJECT (button),
                       "clicked",
                       GTK_SIGNAL_FUNC (set_location_callback),
                       GTK_OBJECT (control_window));
   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
 
+  button = gtk_button_new_with_label ("Move to current position");
+  gtk_signal_connect (GTK_OBJECT (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (move_to_position_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  
   button = gtk_check_button_new_with_label ("Allow shrink");
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
   gtk_signal_connect (GTK_OBJECT (button),
@@ -8424,6 +8700,44 @@ window_controls (GtkWidget *window)
                       control_window);
 
   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
+
+
+  menu = gtk_menu_new ();
+  
+  i = 0;
+  while (i < 5)
+    {
+      GtkWidget *mi;
+      static gchar *names[] = {
+        "GTK_WIN_POS_NONE",
+        "GTK_WIN_POS_CENTER",
+        "GTK_WIN_POS_MOUSE",
+        "GTK_WIN_POS_CENTER_ALWAYS",
+        "GTK_WIN_POS_CENTER_ON_PARENT",
+        NULL
+      };
+
+      g_assert (names[i]);
+      
+      mi = gtk_menu_item_new_with_label (names[i]);
+
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+      ++i;
+    }
+  
+  gtk_widget_show_all (menu);
+  
+  om = gtk_option_menu_new ();
+  gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
+  
+
+  gtk_signal_connect (GTK_OBJECT (om),
+                      "changed",
+                      GTK_SIGNAL_FUNC (pos_selected),
+                      control_window);
+
+  gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
   
   gtk_widget_show_all (vbox);
   
@@ -8434,27 +8748,36 @@ void
 create_window_sizing (void)
 {
   static GtkWidget *window = NULL;
+  static GtkWidget *target_window = NULL;
   
-  if (!window)
+  if (!target_window)
     {
       GtkWidget *label;
       
-      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
       label = gtk_label_new (NULL);
       gtk_label_set_markup (GTK_LABEL (label), "<span foreground=\"purple\"><big>Window being resized</big></span>\nBlah blah blah blah\nblah blah blah\nblah blah blah blah blah");
-      gtk_container_add (GTK_CONTAINER (window), label);
+      gtk_container_add (GTK_CONTAINER (target_window), label);
       gtk_widget_show (label);
       
+      gtk_signal_connect (GTK_OBJECT (target_window), "destroy",
+                         GTK_SIGNAL_FUNC (gtk_widget_destroyed),
+                         &target_window);
+
+      window = window_controls (target_window);
+      
       gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                         GTK_SIGNAL_FUNC(gtk_widget_destroyed),
+                         GTK_SIGNAL_FUNC (gtk_widget_destroyed),
                          &window);
-
-      gtk_window_set_title (GTK_WINDOW (window), "Window to size");
-
-      gtk_widget_show (window_controls (window));
+      
+      gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
     }
 
+  /* don't show target window by default, we want to allow testing
+   * of behavior on first show.
+   */
+  
   if (!GTK_WIDGET_VISIBLE (window))
     gtk_widget_show (window);
   else